1 /* 2 * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package jdk.internal.classfile.impl.verifier; 26 27 import java.lang.classfile.ClassFile; 28 import java.lang.classfile.ClassHierarchyResolver; 29 import java.lang.classfile.ClassModel; 30 import jdk.internal.classfile.components.ClassPrinter; 31 32 import java.lang.classfile.FieldModel; 33 import java.lang.classfile.constantpool.NameAndTypeEntry; 34 import java.lang.constant.ConstantDescs; 35 import java.lang.reflect.AccessFlag; 36 import java.util.ArrayList; 37 import java.util.Collections; 38 import java.util.HashSet; 39 import java.util.List; 40 import java.util.Objects; 41 import java.util.Set; 42 import java.util.function.Consumer; 43 44 import jdk.internal.classfile.impl.ClassHierarchyImpl; 45 import jdk.internal.classfile.impl.RawBytecodeHelper; 46 import jdk.internal.classfile.impl.TemporaryConstantPool; 47 import jdk.internal.classfile.impl.Util; 48 import jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType; 49 import jdk.internal.classfile.impl.verifier.VerificationWrapper.ConstantPoolWrapper; 50 51 import static jdk.internal.classfile.impl.RawBytecodeHelper.*; 52 import static jdk.internal.classfile.impl.verifier.VerificationFrame.FLAG_THIS_UNINIT; 53 import static jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType.T_BOOLEAN; 54 import static jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType.T_LONG; 55 56 /// VerifierImpl performs selected checks and verifications of the class file 57 /// format according to {@jvms 4.8 Format Checking}, 58 /// {@jvms 4.9 Constraints on Java Virtual Machine code}, 59 /// {@jvms 4.10 Verification of class Files} and {@jvms 6.5 Instructions} 60 /// 61 /// From `verifier.cpp`. 62 public final class VerifierImpl { 63 static final int 64 JVM_CONSTANT_Utf8 = 1, 65 JVM_CONSTANT_Unicode = 2, 66 JVM_CONSTANT_Integer = 3, 67 JVM_CONSTANT_Float = 4, 68 JVM_CONSTANT_Long = 5, 69 JVM_CONSTANT_Double = 6, 70 JVM_CONSTANT_Class = 7, 71 JVM_CONSTANT_String = 8, 72 JVM_CONSTANT_Fieldref = 9, 73 JVM_CONSTANT_Methodref = 10, 74 JVM_CONSTANT_InterfaceMethodref = 11, 75 JVM_CONSTANT_NameAndType = 12, 76 JVM_CONSTANT_MethodHandle = 15, 77 JVM_CONSTANT_MethodType = 16, 78 JVM_CONSTANT_Dynamic = 17, 79 JVM_CONSTANT_InvokeDynamic = 18, 80 JVM_CONSTANT_Module = 19, 81 JVM_CONSTANT_Package = 20, 82 JVM_CONSTANT_ExternalMax = 20; 83 84 static final char JVM_SIGNATURE_SPECIAL = '<', 85 JVM_SIGNATURE_ARRAY = '[', 86 JVM_SIGNATURE_BYTE = 'B', 87 JVM_SIGNATURE_CHAR = 'C', 88 JVM_SIGNATURE_CLASS = 'L', 89 JVM_SIGNATURE_FLOAT = 'F', 90 JVM_SIGNATURE_DOUBLE = 'D', 91 JVM_SIGNATURE_INT = 'I', 92 JVM_SIGNATURE_LONG = 'J', 93 JVM_SIGNATURE_SHORT = 'S', 94 JVM_SIGNATURE_BOOLEAN = 'Z'; 95 96 static final String java_lang_String = "java/lang/String"; 97 static final String object_initializer_name = "<init>"; 98 static final String java_lang_invoke_MethodHandle = "java/lang/invoke/MethodHandle"; 99 static final String java_lang_Object = "java/lang/Object"; 100 static final String java_lang_invoke_MethodType = "java/lang/invoke/MethodType"; 101 static final String java_lang_Throwable = "java/lang/Throwable"; 102 static final String java_lang_Class = "java/lang/Class"; 103 104 String errorContext = ""; 105 private int bci; 106 107 static void log_info(Consumer<String> logger, String messageFormat, Object... args) { 108 if (logger != null) logger.accept(String.format(messageFormat + "%n", args)); 109 } 110 private final Consumer<String> _logger; 111 void log_info(String messageFormat, Object... args) { 112 log_info(_logger, messageFormat, args); 113 } 114 115 116 static final int STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50; 117 static final int INVOKEDYNAMIC_MAJOR_VERSION = 51; 118 static final int NOFAILOVER_MAJOR_VERSION = 51; 119 static final int VALUE_TYPES_MAJOR_VERSION = Util.VALUE_OBJECTS_MAJOR; 120 static final int MAX_CODE_SIZE = 65535; 121 122 public static List<VerifyError> verify(ClassModel classModel, Consumer<String> logger) { 123 return verify(classModel, ClassHierarchyResolver.defaultResolver(), logger); 124 } 125 126 public static List<VerifyError> verify(ClassModel classModel, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) { 127 String clsName = classModel.thisClass().asInternalName(); 128 log_info(logger, "Start class verification for: %s", clsName); 129 try { 130 var klass = new VerificationWrapper(classModel); 131 var errors = new ArrayList<VerifyError>(); 132 errors.addAll(new ParserVerifier(classModel).verify()); 133 if (is_eligible_for_verification(klass)) { 134 if (klass.majorVersion() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) { 135 var verifierErrors = new VerifierImpl(klass, classHierarchyResolver, logger).verify_class(); 136 if (!verifierErrors.isEmpty() && klass.majorVersion() < NOFAILOVER_MAJOR_VERSION) { 137 log_info(logger, "Fail over class verification to old verifier for: %s", klass.thisClassName()); 138 errors.addAll(inference_verify(klass)); 139 } else { 140 errors.addAll(verifierErrors); 141 } 142 } else { 143 errors.addAll(inference_verify(klass)); 144 } 145 } 146 return Collections.unmodifiableList(errors); 147 } finally { 148 log_info(logger, "End class verification for: %s", clsName); 149 } 150 } 151 152 public static boolean is_eligible_for_verification(VerificationWrapper klass) { 153 // 8330606 Not applicable here 154 return true; 155 } 156 157 static List<VerifyError> inference_verify(VerificationWrapper klass) { 158 return List.of(new VerifyError("Inference verification is not supported")); 159 } 160 161 static class sig_as_verification_types { 162 private int _num_args; 163 private ArrayList<VerificationType> _sig_verif_types; 164 165 sig_as_verification_types(ArrayList<VerificationType> sig_verif_types) { 166 this._sig_verif_types = sig_verif_types; 167 this._num_args = 0; 168 } 169 170 int num_args() { 171 return _num_args; 172 } 173 174 void set_num_args(int num_args) { 175 _num_args = num_args; 176 } 177 178 ArrayList<VerificationType> sig_verif_types() { 179 return _sig_verif_types; 180 } 181 } 182 183 VerificationType cp_ref_index_to_type(int index, ConstantPoolWrapper cp) { 184 return cp_index_to_type(cp.refClassIndexAt(index), cp); 185 } 186 187 final VerificationWrapper _klass; 188 final ClassHierarchyImpl _class_hierarchy; 189 VerificationWrapper.MethodWrapper _method; 190 VerificationType _this_type; 191 192 static final int BYTECODE_OFFSET = 1, NEW_OFFSET = 2; 193 194 VerificationWrapper current_class() { 195 return _klass; 196 } 197 198 ClassHierarchyImpl class_hierarchy() { 199 return _class_hierarchy; 200 } 201 202 VerificationType current_type() { 203 return _this_type; 204 } 205 206 VerificationType cp_index_to_type(int index, ConstantPoolWrapper cp) { 207 return VerificationType.reference_type(cp.classNameAt(index)); 208 } 209 210 int change_sig_to_verificationType(VerificationSignature sig_type, VerificationType inference_types[], int inference_type_index) { 211 BasicType bt = sig_type.type(); 212 switch (bt) { 213 case T_OBJECT: 214 case T_ARRAY: 215 String name = sig_type.asSymbol(); 216 inference_types[inference_type_index] = VerificationType.reference_type(name); 217 return 1; 218 case T_LONG: 219 inference_types[inference_type_index] = VerificationType.long_type; 220 inference_types[++inference_type_index] = VerificationType.long2_type; 221 return 2; 222 case T_DOUBLE: 223 inference_types[inference_type_index] = VerificationType.double_type; 224 inference_types[++inference_type_index] = VerificationType.double2_type; 225 return 2; 226 case T_INT: 227 case T_BOOLEAN: 228 case T_BYTE: 229 case T_CHAR: 230 case T_SHORT: 231 inference_types[inference_type_index] = VerificationType.integer_type; 232 return 1; 233 case T_FLOAT: 234 inference_types[inference_type_index] = VerificationType.float_type; 235 return 1; 236 default: 237 verifyError("Should not reach here"); 238 return 1; 239 } 240 } 241 242 private static final int NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION = 51; 243 private static final int STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION = 52; 244 private static final int MAX_ARRAY_DIMENSIONS = 255; 245 246 VerifierImpl(VerificationWrapper klass, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) { 247 _klass = klass; 248 _class_hierarchy = new ClassHierarchyImpl(classHierarchyResolver); 249 _this_type = VerificationType.reference_type(klass.thisClassName()); 250 _logger = logger; 251 } 252 253 private VerificationType object_type() { 254 return VerificationType.reference_type(java_lang_Object); 255 } 256 257 static boolean supports_strict_fields(VerificationWrapper klass) { 258 int ver = klass.majorVersion(); 259 return ver > VALUE_TYPES_MAJOR_VERSION || 260 (ver == VALUE_TYPES_MAJOR_VERSION && klass.clm.minorVersion() == ClassFile.PREVIEW_MINOR_VERSION); 261 } 262 263 List<VerifyError> verify_class() { 264 log_info("Verifying class %s with new format", _klass.thisClassName()); 265 var errors = new ArrayList<VerifyError>(); 266 for (VerificationWrapper.MethodWrapper m : _klass.methods()) { 267 if (m.isNative() || m.isAbstract() || m.isBridge()) { 268 continue; 269 } 270 verify_method(m, errors); 271 } 272 return errors; 273 } 274 275 void translate_signature(String method_sig, sig_as_verification_types sig_verif_types) { 276 var sig_stream = new VerificationSignature(method_sig, true, this); 277 VerificationType[] sig_type = new VerificationType[2]; 278 int sig_i = 0; 279 ArrayList<VerificationType> verif_types = sig_verif_types.sig_verif_types(); 280 while (!sig_stream.atReturnType()) { 281 int n = change_sig_to_verificationType(sig_stream, sig_type, 0); 282 if (n > 2) verifyError("Unexpected signature type"); 283 for (int x = 0; x < n; x++) { 284 verif_types.add(sig_type[x]); 285 } 286 sig_i += n; 287 sig_stream.next(); 288 } 289 sig_verif_types.set_num_args(sig_i); 290 if (sig_stream.type() != BasicType.T_VOID) { 291 int n = change_sig_to_verificationType(sig_stream, sig_type, 0); 292 if (n > 2) verifyError("Unexpected signature return type"); 293 for (int y = 0; y < n; y++) { 294 verif_types.add(sig_type[y]); 295 } 296 } 297 } 298 299 void create_method_sig_entry(sig_as_verification_types sig_verif_types, String method_sig) { 300 translate_signature(method_sig, sig_verif_types); 301 } 302 303 void verify_method(VerificationWrapper.MethodWrapper m, List<VerifyError> errorsCollector) { 304 try { 305 verify_method(m); 306 } catch (VerifyError err) { 307 errorsCollector.add(err); 308 } catch (Error | Exception e) { 309 errorsCollector.add(new VerifyError(e.toString())); 310 } 311 } 312 313 @SuppressWarnings("fallthrough") 314 void verify_method(VerificationWrapper.MethodWrapper m) { 315 _method = m; 316 log_info(_logger, "Verifying method %s%s", m.name(), m.descriptor()); 317 byte[] codeArray = m.codeArray(); 318 if (codeArray == null) verifyError("Missing Code attribute"); 319 int max_locals = m.maxLocals(); 320 int max_stack = m.maxStack(); 321 byte[] stackmap_data = m.stackMapTableRawData(); 322 var cp = m.constantPool(); 323 if (!VerificationSignature.isValidMethodSignature(m.descriptor())) verifyError("Invalid method signature"); 324 325 // Collect the initial strict instance fields 326 Set<NameAndTypeEntry> strict_fields = new HashSet<>(); 327 if (m.name().equals(ConstantDescs.INIT_NAME)) { 328 for (var fs : current_class().clm.fields()) { 329 if (fs.flags().has(AccessFlag.STRICT_INIT) && !fs.flags().has(AccessFlag.STATIC)) { 330 var new_field = TemporaryConstantPool.INSTANCE.nameAndTypeEntry(fs.fieldName(), fs.fieldType()); 331 strict_fields.add(new_field); 332 } 333 } 334 } 335 336 VerificationFrame current_frame = new VerificationFrame(max_locals, max_stack, strict_fields, this); 337 VerificationType return_type = current_frame.set_locals_from_arg(m, current_type()); 338 int stackmap_index = 0; 339 int code_length = m.codeLength(); 340 if (code_length < 1 || code_length > MAX_CODE_SIZE) { 341 verifyError(String.format("Invalid method Code length %d", code_length)); 342 } 343 var code = RawBytecodeHelper.of(codeArray); 344 byte[] code_data = generate_code_data(code); 345 int ex_minmax[] = new int[] {code_length, -1}; 346 verify_exception_handler_table(code_length, code_data, ex_minmax); 347 verify_local_variable_table(code_length, code_data); 348 349 var reader = new VerificationTable.StackMapReader(stackmap_data, code_data, code_length, current_frame, 350 (char) max_locals, (char) max_stack, strict_fields, cp, this); 351 VerificationTable stackmap_table = new VerificationTable(reader, cp, this); 352 353 var bcs = code.start(); 354 boolean no_control_flow = false; 355 int opcode; 356 while (bcs.next()) { 357 opcode = bcs.opcode(); 358 bci = bcs.bci(); 359 current_frame.set_offset(bci); 360 current_frame.set_mark(); 361 stackmap_index = verify_stackmap_table(stackmap_index, bci, current_frame, stackmap_table, no_control_flow); 362 boolean this_uninit = false; 363 boolean verified_exc_handlers = false; 364 { 365 int index; 366 int target; 367 VerificationType type, type2 = null; 368 VerificationType atype; 369 if (bcs.isWide()) { 370 if (opcode != IINC && opcode != ILOAD 371 && opcode != ALOAD && opcode != LLOAD 372 && opcode != ISTORE && opcode != ASTORE 373 && opcode != LSTORE && opcode != FLOAD 374 && opcode != DLOAD && opcode != FSTORE 375 && opcode != DSTORE) { 376 verifyError("Bad wide instruction"); 377 } 378 } 379 if (VerificationBytecodes.is_store_into_local(opcode) && bci >= ex_minmax[0] && bci < ex_minmax[1]) { 380 verify_exception_handler_targets(bci, this_uninit, current_frame, stackmap_table); 381 verified_exc_handlers = true; 382 } 383 switch (opcode) { 384 case NOP : 385 no_control_flow = false; break; 386 case ACONST_NULL : 387 current_frame.push_stack( 388 VerificationType.null_type); 389 no_control_flow = false; break; 390 case ICONST_M1 : 391 case ICONST_0 : 392 case ICONST_1 : 393 case ICONST_2 : 394 case ICONST_3 : 395 case ICONST_4 : 396 case ICONST_5 : 397 current_frame.push_stack( 398 VerificationType.integer_type); 399 no_control_flow = false; break; 400 case LCONST_0 : 401 case LCONST_1 : 402 current_frame.push_stack_2( 403 VerificationType.long_type, 404 VerificationType.long2_type); 405 no_control_flow = false; break; 406 case FCONST_0 : 407 case FCONST_1 : 408 case FCONST_2 : 409 current_frame.push_stack( 410 VerificationType.float_type); 411 no_control_flow = false; break; 412 case DCONST_0 : 413 case DCONST_1 : 414 current_frame.push_stack_2( 415 VerificationType.double_type, 416 VerificationType.double2_type); 417 no_control_flow = false; break; 418 case SIPUSH : 419 case BIPUSH : 420 current_frame.push_stack( 421 VerificationType.integer_type); 422 no_control_flow = false; break; 423 case LDC : 424 verify_ldc( 425 opcode, bcs.getIndexU1(), current_frame, 426 cp, bci); 427 no_control_flow = false; break; 428 case LDC_W : 429 case LDC2_W : 430 verify_ldc( 431 opcode, bcs.getIndexU2(), current_frame, 432 cp, bci); 433 no_control_flow = false; break; 434 case ILOAD : 435 verify_iload(bcs.getIndex(), current_frame); 436 no_control_flow = false; break; 437 case ILOAD_0 : 438 case ILOAD_1 : 439 case ILOAD_2 : 440 case ILOAD_3 : 441 index = opcode - ILOAD_0; 442 verify_iload(index, current_frame); 443 no_control_flow = false; break; 444 case LLOAD : 445 verify_lload(bcs.getIndex(), current_frame); 446 no_control_flow = false; break; 447 case LLOAD_0 : 448 case LLOAD_1 : 449 case LLOAD_2 : 450 case LLOAD_3 : 451 index = opcode - LLOAD_0; 452 verify_lload(index, current_frame); 453 no_control_flow = false; break; 454 case FLOAD : 455 verify_fload(bcs.getIndex(), current_frame); 456 no_control_flow = false; break; 457 case FLOAD_0 : 458 case FLOAD_1 : 459 case FLOAD_2 : 460 case FLOAD_3 : 461 index = opcode - FLOAD_0; 462 verify_fload(index, current_frame); 463 no_control_flow = false; break; 464 case DLOAD : 465 verify_dload(bcs.getIndex(), current_frame); 466 no_control_flow = false; break; 467 case DLOAD_0 : 468 case DLOAD_1 : 469 case DLOAD_2 : 470 case DLOAD_3 : 471 index = opcode - DLOAD_0; 472 verify_dload(index, current_frame); 473 no_control_flow = false; break; 474 case ALOAD : 475 verify_aload(bcs.getIndex(), current_frame); 476 no_control_flow = false; break; 477 case ALOAD_0 : 478 case ALOAD_1 : 479 case ALOAD_2 : 480 case ALOAD_3 : 481 index = opcode - ALOAD_0; 482 verify_aload(index, current_frame); 483 no_control_flow = false; break; 484 case IALOAD : 485 type = current_frame.pop_stack( 486 VerificationType.integer_type); 487 atype = current_frame.pop_stack( 488 VerificationType.reference_check); 489 if (!atype.is_int_array()) { 490 verifyError("Bad type"); 491 } 492 current_frame.push_stack( 493 VerificationType.integer_type); 494 no_control_flow = false; break; 495 case BALOAD : 496 type = current_frame.pop_stack( 497 VerificationType.integer_type); 498 atype = current_frame.pop_stack( 499 VerificationType.reference_check); 500 if (!atype.is_bool_array() && !atype.is_byte_array()) { 501 verifyError("Bad type"); 502 } 503 current_frame.push_stack( 504 VerificationType.integer_type); 505 no_control_flow = false; break; 506 case CALOAD : 507 type = current_frame.pop_stack( 508 VerificationType.integer_type); 509 atype = current_frame.pop_stack( 510 VerificationType.reference_check); 511 if (!atype.is_char_array()) { 512 verifyError("Bad type"); 513 } 514 current_frame.push_stack( 515 VerificationType.integer_type); 516 no_control_flow = false; break; 517 case SALOAD : 518 type = current_frame.pop_stack( 519 VerificationType.integer_type); 520 atype = current_frame.pop_stack( 521 VerificationType.reference_check); 522 if (!atype.is_short_array()) { 523 verifyError("Bad type"); 524 } 525 current_frame.push_stack( 526 VerificationType.integer_type); 527 no_control_flow = false; break; 528 case LALOAD : 529 type = current_frame.pop_stack( 530 VerificationType.integer_type); 531 atype = current_frame.pop_stack( 532 VerificationType.reference_check); 533 if (!atype.is_long_array()) { 534 verifyError("Bad type"); 535 } 536 current_frame.push_stack_2( 537 VerificationType.long_type, 538 VerificationType.long2_type); 539 no_control_flow = false; break; 540 case FALOAD : 541 type = current_frame.pop_stack( 542 VerificationType.integer_type); 543 atype = current_frame.pop_stack( 544 VerificationType.reference_check); 545 if (!atype.is_float_array()) { 546 verifyError("Bad type"); 547 } 548 current_frame.push_stack( 549 VerificationType.float_type); 550 no_control_flow = false; break; 551 case DALOAD : 552 type = current_frame.pop_stack( 553 VerificationType.integer_type); 554 atype = current_frame.pop_stack( 555 VerificationType.reference_check); 556 if (!atype.is_double_array()) { 557 verifyError("Bad type"); 558 } 559 current_frame.push_stack_2( 560 VerificationType.double_type, 561 VerificationType.double2_type); 562 no_control_flow = false; break; 563 case AALOAD : { 564 type = current_frame.pop_stack( 565 VerificationType.integer_type); 566 atype = current_frame.pop_stack( 567 VerificationType.reference_check); 568 if (!atype.is_reference_array()) { 569 verifyError("Bad type"); 570 } 571 if (atype.is_null()) { 572 current_frame.push_stack( 573 VerificationType.null_type); 574 } else { 575 VerificationType component = 576 atype.get_component(this); 577 current_frame.push_stack(component); 578 } 579 no_control_flow = false; break; 580 } 581 case ISTORE : 582 verify_istore(bcs.getIndex(), current_frame); 583 no_control_flow = false; break; 584 case ISTORE_0 : 585 case ISTORE_1 : 586 case ISTORE_2 : 587 case ISTORE_3 : 588 index = opcode - ISTORE_0; 589 verify_istore(index, current_frame); 590 no_control_flow = false; break; 591 case LSTORE : 592 verify_lstore(bcs.getIndex(), current_frame); 593 no_control_flow = false; break; 594 case LSTORE_0 : 595 case LSTORE_1 : 596 case LSTORE_2 : 597 case LSTORE_3 : 598 index = opcode - LSTORE_0; 599 verify_lstore(index, current_frame); 600 no_control_flow = false; break; 601 case FSTORE : 602 verify_fstore(bcs.getIndex(), current_frame); 603 no_control_flow = false; break; 604 case FSTORE_0 : 605 case FSTORE_1 : 606 case FSTORE_2 : 607 case FSTORE_3 : 608 index = opcode - FSTORE_0; 609 verify_fstore(index, current_frame); 610 no_control_flow = false; break; 611 case DSTORE : 612 verify_dstore(bcs.getIndex(), current_frame); 613 no_control_flow = false; break; 614 case DSTORE_0 : 615 case DSTORE_1 : 616 case DSTORE_2 : 617 case DSTORE_3 : 618 index = opcode - DSTORE_0; 619 verify_dstore(index, current_frame); 620 no_control_flow = false; break; 621 case ASTORE : 622 verify_astore(bcs.getIndex(), current_frame); 623 no_control_flow = false; break; 624 case ASTORE_0 : 625 case ASTORE_1 : 626 case ASTORE_2 : 627 case ASTORE_3 : 628 index = opcode - ASTORE_0; 629 verify_astore(index, current_frame); 630 no_control_flow = false; break; 631 case IASTORE : 632 type = current_frame.pop_stack( 633 VerificationType.integer_type); 634 type2 = current_frame.pop_stack( 635 VerificationType.integer_type); 636 atype = current_frame.pop_stack( 637 VerificationType.reference_check); 638 if (!atype.is_int_array()) { 639 verifyError("Bad type"); 640 } 641 no_control_flow = false; break; 642 case BASTORE : 643 type = current_frame.pop_stack( 644 VerificationType.integer_type); 645 type2 = current_frame.pop_stack( 646 VerificationType.integer_type); 647 atype = current_frame.pop_stack( 648 VerificationType.reference_check); 649 if (!atype.is_bool_array() && !atype.is_byte_array()) { 650 verifyError("Bad type"); 651 } 652 no_control_flow = false; break; 653 case CASTORE : 654 current_frame.pop_stack( 655 VerificationType.integer_type); 656 current_frame.pop_stack( 657 VerificationType.integer_type); 658 atype = current_frame.pop_stack( 659 VerificationType.reference_check); 660 if (!atype.is_char_array()) { 661 verifyError("Bad type"); 662 } 663 no_control_flow = false; break; 664 case SASTORE : 665 current_frame.pop_stack( 666 VerificationType.integer_type); 667 current_frame.pop_stack( 668 VerificationType.integer_type); 669 atype = current_frame.pop_stack( 670 VerificationType.reference_check); 671 if (!atype.is_short_array()) { 672 verifyError("Bad type"); 673 } 674 no_control_flow = false; break; 675 case LASTORE : 676 current_frame.pop_stack_2( 677 VerificationType.long2_type, 678 VerificationType.long_type); 679 current_frame.pop_stack( 680 VerificationType.integer_type); 681 atype = current_frame.pop_stack( 682 VerificationType.reference_check); 683 if (!atype.is_long_array()) { 684 verifyError("Bad type"); 685 } 686 no_control_flow = false; break; 687 case FASTORE : 688 current_frame.pop_stack( 689 VerificationType.float_type); 690 current_frame.pop_stack 691 (VerificationType.integer_type); 692 atype = current_frame.pop_stack( 693 VerificationType.reference_check); 694 if (!atype.is_float_array()) { 695 verifyError("Bad type"); 696 } 697 no_control_flow = false; break; 698 case DASTORE : 699 current_frame.pop_stack_2( 700 VerificationType.double2_type, 701 VerificationType.double_type); 702 current_frame.pop_stack( 703 VerificationType.integer_type); 704 atype = current_frame.pop_stack( 705 VerificationType.reference_check); 706 if (!atype.is_double_array()) { 707 verifyError("Bad type"); 708 } 709 no_control_flow = false; break; 710 case AASTORE : 711 type = current_frame.pop_stack(object_type()); 712 type2 = current_frame.pop_stack( 713 VerificationType.integer_type); 714 atype = current_frame.pop_stack( 715 VerificationType.reference_check); 716 // more type-checking is done at runtime 717 if (!atype.is_reference_array()) { 718 verifyError("Bad type"); 719 } 720 // 4938384: relaxed constraint in JVMS 3nd edition. 721 no_control_flow = false; break; 722 case POP : 723 current_frame.pop_stack( 724 VerificationType.category1_check); 725 no_control_flow = false; break; 726 case POP2 : 727 type = current_frame.pop_stack(); 728 if (type.is_category1(this)) { 729 current_frame.pop_stack( 730 VerificationType.category1_check); 731 } else if (type.is_category2_2nd()) { 732 current_frame.pop_stack( 733 VerificationType.category2_check); 734 } else { 735 verifyError("Bad type"); 736 } 737 no_control_flow = false; break; 738 case DUP : 739 type = current_frame.pop_stack( 740 VerificationType.category1_check); 741 current_frame.push_stack(type); 742 current_frame.push_stack(type); 743 no_control_flow = false; break; 744 case DUP_X1 : 745 type = current_frame.pop_stack( 746 VerificationType.category1_check); 747 type2 = current_frame.pop_stack( 748 VerificationType.category1_check); 749 current_frame.push_stack(type); 750 current_frame.push_stack(type2); 751 current_frame.push_stack(type); 752 no_control_flow = false; break; 753 case DUP_X2 : 754 { 755 VerificationType type3 = null; 756 type = current_frame.pop_stack( 757 VerificationType.category1_check); 758 type2 = current_frame.pop_stack(); 759 if (type2.is_category1(this)) { 760 type3 = current_frame.pop_stack( 761 VerificationType.category1_check); 762 } else if (type2.is_category2_2nd()) { 763 type3 = current_frame.pop_stack( 764 VerificationType.category2_check); 765 } else { 766 verifyError("Bad type"); 767 } 768 current_frame.push_stack(type); 769 current_frame.push_stack(type3); 770 current_frame.push_stack(type2); 771 current_frame.push_stack(type); 772 no_control_flow = false; break; 773 } 774 case DUP2 : 775 type = current_frame.pop_stack(); 776 if (type.is_category1(this)) { 777 type2 = current_frame.pop_stack( 778 VerificationType.category1_check); 779 } else if (type.is_category2_2nd()) { 780 type2 = current_frame.pop_stack( 781 VerificationType.category2_check); 782 } else { 783 verifyError("Bad type"); 784 } 785 current_frame.push_stack(type2); 786 current_frame.push_stack(type); 787 current_frame.push_stack(type2); 788 current_frame.push_stack(type); 789 no_control_flow = false; break; 790 case DUP2_X1 : 791 { 792 VerificationType type3; 793 type = current_frame.pop_stack(); 794 if (type.is_category1(this)) { 795 type2 = current_frame.pop_stack( 796 VerificationType.category1_check); 797 } else if (type.is_category2_2nd()) { 798 type2 = current_frame.pop_stack( 799 VerificationType.category2_check); 800 } else { 801 verifyError("Bad type"); 802 } 803 type3 = current_frame.pop_stack( 804 VerificationType.category1_check); 805 current_frame.push_stack(type2); 806 current_frame.push_stack(type); 807 current_frame.push_stack(type3); 808 current_frame.push_stack(type2); 809 current_frame.push_stack(type); 810 no_control_flow = false; break; 811 } 812 case DUP2_X2 : 813 VerificationType type3, type4 = null; 814 type = current_frame.pop_stack(); 815 if (type.is_category1(this)) { 816 type2 = current_frame.pop_stack( 817 VerificationType.category1_check); 818 } else if (type.is_category2_2nd()) { 819 type2 = current_frame.pop_stack( 820 VerificationType.category2_check); 821 } else { 822 verifyError("Bad type"); 823 } 824 type3 = current_frame.pop_stack(); 825 if (type3.is_category1(this)) { 826 type4 = current_frame.pop_stack( 827 VerificationType.category1_check); 828 } else if (type3.is_category2_2nd()) { 829 type4 = current_frame.pop_stack( 830 VerificationType.category2_check); 831 } else { 832 verifyError("Bad type"); 833 } 834 current_frame.push_stack(type2); 835 current_frame.push_stack(type); 836 current_frame.push_stack(type4); 837 current_frame.push_stack(type3); 838 current_frame.push_stack(type2); 839 current_frame.push_stack(type); 840 no_control_flow = false; break; 841 case SWAP : 842 type = current_frame.pop_stack( 843 VerificationType.category1_check); 844 type2 = current_frame.pop_stack( 845 VerificationType.category1_check); 846 current_frame.push_stack(type); 847 current_frame.push_stack(type2); 848 no_control_flow = false; break; 849 case IADD : 850 case ISUB : 851 case IMUL : 852 case IDIV : 853 case IREM : 854 case ISHL : 855 case ISHR : 856 case IUSHR : 857 case IOR : 858 case IXOR : 859 case IAND : 860 current_frame.pop_stack( 861 VerificationType.integer_type); 862 // fall through 863 case INEG : 864 current_frame.pop_stack( 865 VerificationType.integer_type); 866 current_frame.push_stack( 867 VerificationType.integer_type); 868 no_control_flow = false; break; 869 case LADD : 870 case LSUB : 871 case LMUL : 872 case LDIV : 873 case LREM : 874 case LAND : 875 case LOR : 876 case LXOR : 877 current_frame.pop_stack_2( 878 VerificationType.long2_type, 879 VerificationType.long_type); 880 // fall through 881 case LNEG : 882 current_frame.pop_stack_2( 883 VerificationType.long2_type, 884 VerificationType.long_type); 885 current_frame.push_stack_2( 886 VerificationType.long_type, 887 VerificationType.long2_type); 888 no_control_flow = false; break; 889 case LSHL : 890 case LSHR : 891 case LUSHR : 892 current_frame.pop_stack( 893 VerificationType.integer_type); 894 current_frame.pop_stack_2( 895 VerificationType.long2_type, 896 VerificationType.long_type); 897 current_frame.push_stack_2( 898 VerificationType.long_type, 899 VerificationType.long2_type); 900 no_control_flow = false; break; 901 case FADD : 902 case FSUB : 903 case FMUL : 904 case FDIV : 905 case FREM : 906 current_frame.pop_stack( 907 VerificationType.float_type); 908 // fall through 909 case FNEG : 910 current_frame.pop_stack( 911 VerificationType.float_type); 912 current_frame.push_stack( 913 VerificationType.float_type); 914 no_control_flow = false; break; 915 case DADD : 916 case DSUB : 917 case DMUL : 918 case DDIV : 919 case DREM : 920 current_frame.pop_stack_2( 921 VerificationType.double2_type, 922 VerificationType.double_type); 923 // fall through 924 case DNEG : 925 current_frame.pop_stack_2( 926 VerificationType.double2_type, 927 VerificationType.double_type); 928 current_frame.push_stack_2( 929 VerificationType.double_type, 930 VerificationType.double2_type); 931 no_control_flow = false; break; 932 case IINC : 933 verify_iinc(bcs.getIndex(), current_frame); 934 no_control_flow = false; break; 935 case I2L : 936 type = current_frame.pop_stack( 937 VerificationType.integer_type); 938 current_frame.push_stack_2( 939 VerificationType.long_type, 940 VerificationType.long2_type); 941 no_control_flow = false; break; 942 case L2I : 943 current_frame.pop_stack_2( 944 VerificationType.long2_type, 945 VerificationType.long_type); 946 current_frame.push_stack( 947 VerificationType.integer_type); 948 no_control_flow = false; break; 949 case I2F : 950 current_frame.pop_stack( 951 VerificationType.integer_type); 952 current_frame.push_stack( 953 VerificationType.float_type); 954 no_control_flow = false; break; 955 case I2D : 956 current_frame.pop_stack( 957 VerificationType.integer_type); 958 current_frame.push_stack_2( 959 VerificationType.double_type, 960 VerificationType.double2_type); 961 no_control_flow = false; break; 962 case L2F : 963 current_frame.pop_stack_2( 964 VerificationType.long2_type, 965 VerificationType.long_type); 966 current_frame.push_stack( 967 VerificationType.float_type); 968 no_control_flow = false; break; 969 case L2D : 970 current_frame.pop_stack_2( 971 VerificationType.long2_type, 972 VerificationType.long_type); 973 current_frame.push_stack_2( 974 VerificationType.double_type, 975 VerificationType.double2_type); 976 no_control_flow = false; break; 977 case F2I : 978 current_frame.pop_stack( 979 VerificationType.float_type); 980 current_frame.push_stack( 981 VerificationType.integer_type); 982 no_control_flow = false; break; 983 case F2L : 984 current_frame.pop_stack( 985 VerificationType.float_type); 986 current_frame.push_stack_2( 987 VerificationType.long_type, 988 VerificationType.long2_type); 989 no_control_flow = false; break; 990 case F2D : 991 current_frame.pop_stack( 992 VerificationType.float_type); 993 current_frame.push_stack_2( 994 VerificationType.double_type, 995 VerificationType.double2_type); 996 no_control_flow = false; break; 997 case D2I : 998 current_frame.pop_stack_2( 999 VerificationType.double2_type, 1000 VerificationType.double_type); 1001 current_frame.push_stack( 1002 VerificationType.integer_type); 1003 no_control_flow = false; break; 1004 case D2L : 1005 current_frame.pop_stack_2( 1006 VerificationType.double2_type, 1007 VerificationType.double_type); 1008 current_frame.push_stack_2( 1009 VerificationType.long_type, 1010 VerificationType.long2_type); 1011 no_control_flow = false; break; 1012 case D2F : 1013 current_frame.pop_stack_2( 1014 VerificationType.double2_type, 1015 VerificationType.double_type); 1016 current_frame.push_stack( 1017 VerificationType.float_type); 1018 no_control_flow = false; break; 1019 case I2B : 1020 case I2C : 1021 case I2S : 1022 current_frame.pop_stack( 1023 VerificationType.integer_type); 1024 current_frame.push_stack( 1025 VerificationType.integer_type); 1026 no_control_flow = false; break; 1027 case LCMP : 1028 current_frame.pop_stack_2( 1029 VerificationType.long2_type, 1030 VerificationType.long_type); 1031 current_frame.pop_stack_2( 1032 VerificationType.long2_type, 1033 VerificationType.long_type); 1034 current_frame.push_stack( 1035 VerificationType.integer_type); 1036 no_control_flow = false; break; 1037 case FCMPL : 1038 case FCMPG : 1039 current_frame.pop_stack( 1040 VerificationType.float_type); 1041 current_frame.pop_stack( 1042 VerificationType.float_type); 1043 current_frame.push_stack( 1044 VerificationType.integer_type); 1045 no_control_flow = false; break; 1046 case DCMPL : 1047 case DCMPG : 1048 current_frame.pop_stack_2( 1049 VerificationType.double2_type, 1050 VerificationType.double_type); 1051 current_frame.pop_stack_2( 1052 VerificationType.double2_type, 1053 VerificationType.double_type); 1054 current_frame.push_stack( 1055 VerificationType.integer_type); 1056 no_control_flow = false; break; 1057 case IF_ICMPEQ: 1058 case IF_ICMPNE: 1059 case IF_ICMPLT: 1060 case IF_ICMPGE: 1061 case IF_ICMPGT: 1062 case IF_ICMPLE: 1063 current_frame.pop_stack( 1064 VerificationType.integer_type); 1065 // fall through 1066 case IFEQ: 1067 case IFNE: 1068 case IFLT: 1069 case IFGE: 1070 case IFGT: 1071 case IFLE: 1072 current_frame.pop_stack( 1073 VerificationType.integer_type); 1074 target = bcs.dest(); 1075 stackmap_table.check_jump_target( 1076 current_frame, target); 1077 no_control_flow = false; break; 1078 case IF_ACMPEQ : 1079 case IF_ACMPNE : 1080 current_frame.pop_stack(object_type()); 1081 // fall through 1082 case IFNULL : 1083 case IFNONNULL : 1084 current_frame.pop_stack(object_type()); 1085 target = bcs.dest(); 1086 stackmap_table.check_jump_target 1087 (current_frame, target); 1088 no_control_flow = false; break; 1089 case GOTO : 1090 target = bcs.dest(); 1091 stackmap_table.check_jump_target( 1092 current_frame, target); 1093 no_control_flow = true; break; 1094 case GOTO_W : 1095 target = bcs.destW(); 1096 stackmap_table.check_jump_target( 1097 current_frame, target); 1098 no_control_flow = true; break; 1099 case TABLESWITCH : 1100 case LOOKUPSWITCH : 1101 verify_switch( 1102 bcs, code_length, code_data, current_frame, 1103 stackmap_table); 1104 no_control_flow = true; break; 1105 case IRETURN : 1106 type = current_frame.pop_stack( 1107 VerificationType.integer_type); 1108 verify_return_value(return_type, type, bci, 1109 current_frame); 1110 no_control_flow = true; break; 1111 case LRETURN : 1112 type2 = current_frame.pop_stack( 1113 VerificationType.long2_type); 1114 type = current_frame.pop_stack( 1115 VerificationType.long_type); 1116 verify_return_value(return_type, type, bci, 1117 current_frame); 1118 no_control_flow = true; break; 1119 case FRETURN : 1120 type = current_frame.pop_stack( 1121 VerificationType.float_type); 1122 verify_return_value(return_type, type, bci, 1123 current_frame); 1124 no_control_flow = true; break; 1125 case DRETURN : 1126 type2 = current_frame.pop_stack( 1127 VerificationType.double2_type); 1128 type = current_frame.pop_stack( 1129 VerificationType.double_type); 1130 verify_return_value(return_type, type, bci, 1131 current_frame); 1132 no_control_flow = true; break; 1133 case ARETURN : 1134 type = current_frame.pop_stack( 1135 VerificationType.reference_check); 1136 verify_return_value(return_type, type, bci, 1137 current_frame); 1138 no_control_flow = true; break; 1139 case RETURN: 1140 if (!return_type.is_bogus()) { 1141 verifyError("Method expects a return value"); 1142 } 1143 if (object_initializer_name.equals(_method.name()) && 1144 current_frame.flag_this_uninit()) { 1145 verifyError("Constructor must call super() or this() before return"); 1146 } 1147 no_control_flow = true; break; 1148 case GETSTATIC : 1149 case PUTSTATIC : 1150 verify_field_instructions(bcs, current_frame, cp, true); 1151 no_control_flow = false; break; 1152 case GETFIELD : 1153 case PUTFIELD : 1154 verify_field_instructions(bcs, current_frame, cp, false); 1155 no_control_flow = false; break; 1156 case INVOKEVIRTUAL : 1157 case INVOKESPECIAL : 1158 case INVOKESTATIC : 1159 this_uninit = verify_invoke_instructions(bcs, code_length, current_frame, (bci >= ex_minmax[0] && bci < ex_minmax[1]), this_uninit, return_type, cp, stackmap_table); 1160 no_control_flow = false; break; 1161 case INVOKEINTERFACE : 1162 case INVOKEDYNAMIC : 1163 this_uninit = verify_invoke_instructions(bcs, code_length, current_frame, (bci >= ex_minmax[0] && bci < ex_minmax[1]), this_uninit, return_type, cp, stackmap_table); 1164 no_control_flow = false; break; 1165 case NEW : 1166 { 1167 index = bcs.getIndexU2(); 1168 verify_cp_class_type(bci, index, cp); 1169 VerificationType new_class_type = 1170 cp_index_to_type(index, cp); 1171 if (!new_class_type.is_object()) { 1172 verifyError("Illegal new instruction"); 1173 } 1174 type = VerificationType.uninitialized_type(bci); 1175 current_frame.push_stack(type); 1176 no_control_flow = false; break; 1177 } 1178 case NEWARRAY : 1179 type = get_newarray_type(bcs.getIndex(), bci); 1180 current_frame.pop_stack( 1181 VerificationType.integer_type); 1182 current_frame.push_stack(type); 1183 no_control_flow = false; break; 1184 case ANEWARRAY : 1185 verify_anewarray(bci, bcs.getIndexU2(), cp, current_frame); 1186 no_control_flow = false; break; 1187 case ARRAYLENGTH : 1188 type = current_frame.pop_stack( 1189 VerificationType.reference_check); 1190 if (!(type.is_null() || type.is_array())) { 1191 verifyError("Bad type"); 1192 } 1193 current_frame.push_stack( 1194 VerificationType.integer_type); 1195 no_control_flow = false; break; 1196 case CHECKCAST : 1197 { 1198 index = bcs.getIndexU2(); 1199 verify_cp_class_type(bci, index, cp); 1200 current_frame.pop_stack(object_type()); 1201 VerificationType klass_type = cp_index_to_type( 1202 index, cp); 1203 current_frame.push_stack(klass_type); 1204 no_control_flow = false; break; 1205 } 1206 case INSTANCEOF : { 1207 index = bcs.getIndexU2(); 1208 verify_cp_class_type(bci, index, cp); 1209 current_frame.pop_stack(object_type()); 1210 current_frame.push_stack( 1211 VerificationType.integer_type); 1212 no_control_flow = false; break; 1213 } 1214 case MONITORENTER : 1215 case MONITOREXIT : 1216 current_frame.pop_stack( 1217 VerificationType.reference_check); 1218 no_control_flow = false; break; 1219 case MULTIANEWARRAY : 1220 { 1221 index = bcs.getIndexU2(); 1222 int dim = _method.codeArray()[bcs.bci() +3] & 0xff; 1223 verify_cp_class_type(bci, index, cp); 1224 VerificationType new_array_type = 1225 cp_index_to_type(index, cp); 1226 if (!new_array_type.is_array()) { 1227 verifyError("Illegal constant pool index in multianewarray instruction"); 1228 } 1229 if (dim < 1 || new_array_type.dimensions(this) < dim) { 1230 verifyError(String.format("Illegal dimension in multianewarray instruction: %d", dim)); 1231 } 1232 for (int i = 0; i < dim; i++) { 1233 current_frame.pop_stack( 1234 VerificationType.integer_type); 1235 } 1236 current_frame.push_stack(new_array_type); 1237 no_control_flow = false; break; 1238 } 1239 case ATHROW : 1240 type = VerificationType.reference_type(java_lang_Throwable); 1241 current_frame.pop_stack(type); 1242 no_control_flow = true; break; 1243 default: 1244 verifyError(String.format("Bad instruction: %02x", opcode)); 1245 } 1246 } 1247 if (verified_exc_handlers && this_uninit) verifyError("Exception handler targets got verified before this_uninit got set"); 1248 if (!verified_exc_handlers && bci >= ex_minmax[0] && bci < ex_minmax[1]) { 1249 verify_exception_handler_targets(bci, this_uninit, current_frame, stackmap_table); 1250 } 1251 } 1252 if (!no_control_flow) { 1253 verifyError("Control flow falls through code end"); 1254 } 1255 } 1256 1257 private byte[] generate_code_data(RawBytecodeHelper.CodeRange code) { 1258 byte[] code_data = new byte[code.length()]; 1259 var bcs = code.start(); 1260 while (bcs.next()) { 1261 if (bcs.opcode() != ILLEGAL) { 1262 int bci = bcs.bci(); 1263 if (bcs.opcode() == NEW) { 1264 code_data[bci] = NEW_OFFSET; 1265 } else { 1266 code_data[bci] = BYTECODE_OFFSET; 1267 } 1268 } else { 1269 verifyError("Bad instruction"); 1270 } 1271 } 1272 return code_data; 1273 } 1274 1275 void verify_exception_handler_table(int code_length, byte[] code_data, int[] minmax) { 1276 var cp = _method.constantPool(); 1277 for (var exhandler : _method.exceptionTable()) { 1278 int start_pc = exhandler[0]; 1279 int end_pc = exhandler[1]; 1280 int handler_pc = exhandler[2]; 1281 if (start_pc >= code_length || code_data[start_pc] == 0) { 1282 classError(String.format("Illegal exception table start_pc %d", start_pc)); 1283 } 1284 if (end_pc != code_length) { 1285 if (end_pc > code_length || code_data[end_pc] == 0) { 1286 classError(String.format("Illegal exception table end_pc %d", end_pc)); 1287 } 1288 } 1289 if (handler_pc >= code_length || code_data[handler_pc] == 0) { 1290 classError(String.format("Illegal exception table handler_pc %d", handler_pc)); 1291 } 1292 int catch_type_index = exhandler[3]; 1293 if (catch_type_index != 0) { 1294 VerificationType catch_type = cp_index_to_type(catch_type_index, cp); 1295 VerificationType throwable = VerificationType.reference_type(java_lang_Throwable); 1296 // 8267118 Not applicable here 1297 boolean is_subclass = throwable.is_assignable_from(catch_type, this); 1298 if (!is_subclass) { 1299 verifyError(String.format("Catch type is not a subclass of Throwable in exception handler %d", handler_pc)); 1300 } 1301 } 1302 if (start_pc < minmax[0]) minmax[0] = start_pc; 1303 if (end_pc > minmax[1]) minmax[1] = end_pc; 1304 } 1305 } 1306 1307 void verify_local_variable_table(int code_length, byte[] code_data) { 1308 for (var lvte : _method.localVariableTable()) { 1309 int start_bci = lvte.startPc(); 1310 int length = lvte.length(); 1311 if (start_bci >= code_length || code_data[start_bci] == 0) { 1312 classError(String.format("Illegal local variable table start_pc %d", start_bci)); 1313 } 1314 int end_bci = start_bci + length; 1315 if (end_bci != code_length) { 1316 if (end_bci >= code_length || code_data[end_bci] == 0) { 1317 classError(String.format("Illegal local variable table length %d", length)); 1318 } 1319 } 1320 } 1321 } 1322 1323 int verify_stackmap_table(int stackmap_index, int bci, VerificationFrame current_frame, VerificationTable stackmap_table, boolean no_control_flow) { 1324 if (stackmap_index < stackmap_table.get_frame_count()) { 1325 int this_offset = stackmap_table.get_offset(stackmap_index); 1326 if (no_control_flow && this_offset > bci) { 1327 verifyError("Expecting a stack map frame"); 1328 } 1329 if (this_offset == bci) { 1330 boolean matches = stackmap_table.match_stackmap(current_frame, this_offset, stackmap_index, !no_control_flow, true); 1331 if (!matches) { 1332 verifyError("Instruction type does not match stack map"); 1333 } 1334 stackmap_index++; 1335 } else if (this_offset < bci) { 1336 classError(String.format("Bad stack map offset %d", this_offset)); 1337 } 1338 } else if (no_control_flow) { 1339 verifyError("Expecting a stack map frame"); 1340 } 1341 return stackmap_index; 1342 } 1343 1344 void verify_exception_handler_targets(int bci, boolean this_uninit, VerificationFrame current_frame, VerificationTable stackmap_table) { 1345 var cp = _method.constantPool(); 1346 for(var exhandler : _method.exceptionTable()) { 1347 int start_pc = exhandler[0]; 1348 int end_pc = exhandler[1]; 1349 int handler_pc = exhandler[2]; 1350 int catch_type_index = exhandler[3]; 1351 if(bci >= start_pc && bci < end_pc) { 1352 int flags = current_frame.flags(); 1353 if (this_uninit) { flags |= FLAG_THIS_UNINIT; } 1354 VerificationFrame new_frame = current_frame.frame_in_exception_handler(flags); 1355 if (catch_type_index != 0) { 1356 VerificationType catch_type = cp_index_to_type(catch_type_index, cp); 1357 new_frame.push_stack(catch_type); 1358 } else { 1359 VerificationType throwable = VerificationType.reference_type(java_lang_Throwable); 1360 new_frame.push_stack(throwable); 1361 } 1362 boolean matches = stackmap_table.match_stackmap(new_frame, handler_pc, true, false); 1363 if (!matches) { 1364 verifyError(String.format("Stack map does not match the one at exception handler %d", handler_pc)); 1365 } 1366 } 1367 } 1368 } 1369 1370 void verify_cp_index(int bci, ConstantPoolWrapper cp, int index) { 1371 int nconstants = cp.entryCount(); 1372 if ((index <= 0) || (index >= nconstants)) { 1373 verifyError(String.format("Illegal constant pool index %d", index)); 1374 } 1375 } 1376 1377 void verify_cp_type(int bci, int index, ConstantPoolWrapper cp, int types) { 1378 verify_cp_index(bci, cp, index); 1379 int tag = cp.tagAt(index); 1380 if (tag > JVM_CONSTANT_ExternalMax || (types & (1 << tag))== 0) { 1381 verifyError(String.format("Illegal type at constant pool entry %d", index)); 1382 } 1383 } 1384 1385 void verify_cp_class_type(int bci, int index, ConstantPoolWrapper cp) { 1386 verify_cp_index(bci, cp, index); 1387 int tag = cp.tagAt(index); 1388 if (tag != JVM_CONSTANT_Class) { 1389 verifyError(String.format("Illegal type at constant pool entry %d", index)); 1390 } 1391 } 1392 1393 void verify_ldc(int opcode, int index, VerificationFrame current_frame, ConstantPoolWrapper cp, int bci) { 1394 verify_cp_index(bci, cp, index); 1395 int tag = cp.tagAt(index); 1396 int types = 0; 1397 if (opcode == LDC || opcode == LDC_W) { 1398 types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float) 1399 | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class) 1400 | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType) 1401 | (1 << JVM_CONSTANT_Dynamic); 1402 verify_cp_type(bci, index, cp, types); 1403 } else { 1404 if (opcode != LDC2_W) verifyError("must be ldc2_w"); 1405 types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long) | (1 << JVM_CONSTANT_Dynamic); 1406 verify_cp_type(bci, index, cp, types); 1407 } 1408 switch (tag) { 1409 case JVM_CONSTANT_Utf8 -> current_frame.push_stack(object_type()); 1410 case JVM_CONSTANT_String -> current_frame.push_stack(VerificationType.reference_type(java_lang_String)); 1411 case JVM_CONSTANT_Class -> current_frame.push_stack(VerificationType.reference_type(java_lang_Class)); 1412 case JVM_CONSTANT_Integer -> current_frame.push_stack(VerificationType.integer_type); 1413 case JVM_CONSTANT_Float -> current_frame.push_stack(VerificationType.float_type); 1414 case JVM_CONSTANT_Double -> current_frame.push_stack_2(VerificationType.double_type, VerificationType.double2_type); 1415 case JVM_CONSTANT_Long -> current_frame.push_stack_2(VerificationType.long_type, VerificationType.long2_type); 1416 case JVM_CONSTANT_MethodHandle -> current_frame.push_stack(VerificationType.reference_type(java_lang_invoke_MethodHandle)); 1417 case JVM_CONSTANT_MethodType -> current_frame.push_stack(VerificationType.reference_type(java_lang_invoke_MethodType)); 1418 case JVM_CONSTANT_Dynamic -> { 1419 String constant_type = cp.dynamicConstantSignatureAt(index); 1420 if (!VerificationSignature.isValidTypeSignature(constant_type)) verifyError("Invalid type for dynamic constant"); 1421 VerificationType[] v_constant_type = new VerificationType[2]; 1422 var sig_stream = new VerificationSignature(constant_type, false, this); 1423 int n = change_sig_to_verificationType(sig_stream, v_constant_type, 0); 1424 int opcode_n = (opcode == LDC2_W ? 2 : 1); 1425 if (n != opcode_n) { 1426 types &= ~(1 << JVM_CONSTANT_Dynamic); 1427 verify_cp_type(bci, index, cp, types); 1428 } 1429 for (int i = 0; i < n; i++) { 1430 current_frame.push_stack(v_constant_type[i]); 1431 } 1432 } 1433 default -> verifyError("Invalid index in ldc"); 1434 } 1435 } 1436 1437 void verify_switch(RawBytecodeHelper bcs, int code_length, byte[] code_data, VerificationFrame current_frame, VerificationTable stackmap_table) { 1438 int bci = bcs.bci(); 1439 int aligned_bci = VerificationBytecodes.align(bci + 1); 1440 // 4639449 & 4647081: padding bytes must be 0 1441 if (_klass.majorVersion() < NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION) { 1442 int padding_offset = 1; 1443 while ((bci + padding_offset) < aligned_bci) { 1444 if (_method.codeArray()[bci + padding_offset] != 0) { 1445 verifyError("Nonzero padding byte in lookupswitch or tableswitch"); 1446 } 1447 padding_offset++; 1448 } 1449 } 1450 int default_offset = bcs.getIntUnchecked(aligned_bci); 1451 int keys, delta; 1452 current_frame.pop_stack(VerificationType.integer_type); 1453 if (bcs.opcode() == TABLESWITCH) { 1454 int low = bcs.getIntUnchecked(aligned_bci + 4); 1455 int high = bcs.getIntUnchecked(aligned_bci + 2*4); 1456 if (low > high) { 1457 verifyError("low must be less than or equal to high in tableswitch"); 1458 } 1459 long keys64 = ((long) high - low) + 1; 1460 if (keys64 > 65535) { // Max code length 1461 verifyError("too many keys in tableswitch"); 1462 } 1463 keys = (int) keys64; 1464 delta = 1; 1465 } else { 1466 // Make sure that the lookupswitch items are sorted 1467 keys = bcs.getIntUnchecked(aligned_bci + 4); 1468 if (keys < 0) { 1469 verifyError("number of keys in lookupswitch less than 0"); 1470 } 1471 delta = 2; 1472 for (int i = 0; i < (keys - 1); i++) { 1473 int this_key = bcs.getIntUnchecked(aligned_bci + (2+2*i)*4); 1474 int next_key = bcs.getIntUnchecked(aligned_bci + (2+2*i+2)*4); 1475 if (this_key >= next_key) { 1476 verifyError("Bad lookupswitch instruction"); 1477 } 1478 } 1479 } 1480 int target = bci + default_offset; 1481 stackmap_table.check_jump_target(current_frame, target); 1482 for (int i = 0; i < keys; i++) { 1483 aligned_bci = VerificationBytecodes.align(bcs.bci() + 1); 1484 target = bci + bcs.getIntUnchecked(aligned_bci + (3+i*delta)*4); 1485 stackmap_table.check_jump_target(current_frame, target); 1486 } 1487 } 1488 1489 void verify_field_instructions(RawBytecodeHelper bcs, VerificationFrame current_frame, ConstantPoolWrapper cp, boolean allow_arrays) { 1490 int index = bcs.getIndexU2(); 1491 verify_cp_type(bcs.bci(), index, cp, 1 << JVM_CONSTANT_Fieldref); 1492 String field_name = cp.refNameAt(index); 1493 String field_sig = cp.refSignatureAt(index); 1494 if (!VerificationSignature.isValidTypeSignature(field_sig)) verifyError("Invalid field signature"); 1495 VerificationType ref_class_type = cp_ref_index_to_type(index, cp); 1496 if (!ref_class_type.is_object() && 1497 (!allow_arrays || !ref_class_type.is_array())) { 1498 verifyError(String.format("Expecting reference to class in class %s at constant pool index %d", _klass.thisClassName(), index)); 1499 } 1500 VerificationType target_class_type = ref_class_type; 1501 VerificationType[] field_type = new VerificationType[2]; 1502 var sig_stream = new VerificationSignature(field_sig, false, this); 1503 VerificationType stack_object_type = null; 1504 int n = change_sig_to_verificationType(sig_stream, field_type, 0); 1505 boolean is_assignable; 1506 switch (bcs.opcode()) { 1507 case GETSTATIC -> { 1508 for (int i = 0; i < n; i++) { 1509 current_frame.push_stack(field_type[i]); 1510 } 1511 } 1512 case PUTSTATIC -> { 1513 for (int i = n - 1; i >= 0; i--) { 1514 current_frame.pop_stack(field_type[i]); 1515 } 1516 } 1517 case GETFIELD -> { 1518 stack_object_type = current_frame.pop_stack( 1519 target_class_type); 1520 // 8270398 Not applicable here 1521 for (int i = 0; i < n; i++) { 1522 current_frame.push_stack(field_type[i]); 1523 } 1524 } 1525 case PUTFIELD -> { 1526 for (int i = n - 1; i >= 0; i--) { 1527 current_frame.pop_stack(field_type[i]); 1528 } 1529 stack_object_type = current_frame.pop_stack(); 1530 FieldModel fd = _klass.findField(field_name, field_sig); 1531 boolean is_local_field = fd != null && 1532 target_class_type.equals(current_type()); 1533 if (stack_object_type.is_uninitialized_this(this)) { 1534 if (is_local_field) { 1535 // Set the type to the current type so the is_assignable check passes. 1536 stack_object_type = current_type(); 1537 1538 if (fd.flags().has(AccessFlag.STRICT_INIT)) { 1539 current_frame.satisfy_unset_field(fd.fieldName(), fd.fieldType()); 1540 } 1541 } 1542 } else if (supports_strict_fields(_klass)) { 1543 // `strict` fields are not writable, but only local fields produce verification errors 1544 if (is_local_field && fd.flags().has(AccessFlag.STRICT_INIT) && fd.flags().has(AccessFlag.FINAL)) { 1545 verifyError("Bad code %d %s".formatted(bci, 1546 "Illegal use of putfield on a strict field: %s:%s".formatted(fd.fieldName(), fd.fieldType()))); 1547 } 1548 } 1549 is_assignable = target_class_type.is_assignable_from(stack_object_type, this); 1550 if (!is_assignable) { 1551 verifyError("Bad type on operand stack in putfield"); 1552 } 1553 } 1554 default -> verifyError("Should not reach here"); 1555 } 1556 } 1557 1558 // Return TRUE if all code paths starting with start_bc_offset end in 1559 // bytecode athrow or loop. 1560 boolean ends_in_athrow(int start_bc_offset) { 1561 log_info("unimplemented VerifierImpl.ends_in_athrow"); 1562 return true; 1563 } 1564 1565 boolean verify_invoke_init(RawBytecodeHelper bcs, int ref_class_index, VerificationType ref_class_type, 1566 VerificationFrame current_frame, int code_length, boolean in_try_block, 1567 boolean this_uninit, ConstantPoolWrapper cp, VerificationTable stackmap_table) { 1568 int bci = bcs.bci(); 1569 VerificationType type = current_frame.pop_stack(VerificationType.reference_check); 1570 if (type.is_uninitialized_this(this)) { 1571 String superk_name = current_class().superclassName(); 1572 if (!current_class().thisClassName().equals(ref_class_type.name()) && 1573 !superk_name.equals(ref_class_type.name())) { 1574 verifyError("Bad <init> method call"); 1575 } else if (ref_class_type.name().equals(superk_name)) { 1576 // Strict final fields must be satisfied by this point 1577 if (!current_frame.verify_unset_fields_satisfied()) { 1578 current_frame.unsatisfied_strict_fields_error(current_class(), bci); 1579 } 1580 } 1581 if (in_try_block) { 1582 for(var exhandler : _method.exceptionTable()) { 1583 int start_pc = exhandler[0]; 1584 int end_pc = exhandler[1]; 1585 1586 if (bci >= start_pc && bci < end_pc) { 1587 if (!ends_in_athrow(exhandler[2])) { 1588 verifyError("Bad <init> method call from after the start of a try block"); 1589 } 1590 } 1591 } 1592 verify_exception_handler_targets(bci, true, current_frame, stackmap_table); 1593 } 1594 current_frame.initialize_object(type, current_type()); 1595 this_uninit = true; 1596 } else if (type.is_uninitialized()) { 1597 int new_offset = type.bci(this); 1598 if (new_offset > (code_length - 3) || (_method.codeArray()[new_offset] & 0xff) != NEW) { 1599 verifyError("Expecting new instruction"); 1600 } 1601 int new_class_index = bcs.getU2(new_offset + 1); 1602 verify_cp_class_type(bci, new_class_index, cp); 1603 VerificationType new_class_type = cp_index_to_type( 1604 new_class_index, cp); 1605 if (!new_class_type.equals(ref_class_type)) { 1606 verifyError("Call to wrong <init> method"); 1607 } 1608 if (in_try_block) { 1609 verify_exception_handler_targets(bci, this_uninit, current_frame, 1610 stackmap_table); 1611 } 1612 current_frame.initialize_object(type, new_class_type); 1613 } else { 1614 verifyError("Bad operand type when invoking <init>"); 1615 } 1616 return this_uninit; 1617 } 1618 1619 static boolean is_same_or_direct_interface(VerificationWrapper klass, VerificationType klass_type, VerificationType ref_class_type) { 1620 if (ref_class_type.equals(klass_type)) return true; 1621 for (String k_name : klass.interfaceNames()) { 1622 if (ref_class_type.equals(VerificationType.reference_type(k_name))) { 1623 return true; 1624 } 1625 } 1626 return false; 1627 } 1628 1629 boolean verify_invoke_instructions(RawBytecodeHelper bcs, int code_length, VerificationFrame current_frame, boolean in_try_block, boolean this_uninit, VerificationType return_type, ConstantPoolWrapper cp, VerificationTable stackmap_table) { 1630 // Make sure the constant pool item is the right type 1631 int index = bcs.getIndexU2(); 1632 int opcode = bcs.opcode(); 1633 int types = 0; 1634 switch (opcode) { 1635 case INVOKEINTERFACE: 1636 types = 1 << JVM_CONSTANT_InterfaceMethodref; 1637 break; 1638 case INVOKEDYNAMIC: 1639 types = 1 << JVM_CONSTANT_InvokeDynamic; 1640 break; 1641 case INVOKESPECIAL: 1642 case INVOKESTATIC: 1643 types = (_klass.majorVersion() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ? 1644 (1 << JVM_CONSTANT_Methodref) : 1645 ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref)); 1646 break; 1647 default: 1648 types = 1 << JVM_CONSTANT_Methodref; 1649 } 1650 verify_cp_type(bcs.bci(), index, cp, types); 1651 String method_name = cp.refNameAt(index); 1652 String method_sig = cp.refSignatureAt(index); 1653 if (!VerificationSignature.isValidMethodSignature(method_sig)) verifyError("Invalid method signature"); 1654 VerificationType ref_class_type = null; 1655 if (opcode == INVOKEDYNAMIC) { 1656 if (_klass.majorVersion() < INVOKEDYNAMIC_MAJOR_VERSION) { 1657 classError(String.format("invokedynamic instructions not supported by this class file version (%d), class %s", _klass.majorVersion(), _klass.thisClassName())); 1658 } 1659 } else { 1660 ref_class_type = cp_ref_index_to_type(index, cp); 1661 } 1662 String sig = cp.refSignatureAt(index); 1663 sig_as_verification_types mth_sig_verif_types; 1664 ArrayList<VerificationType> verif_types = new ArrayList<>(10); 1665 mth_sig_verif_types = new sig_as_verification_types(verif_types); 1666 create_method_sig_entry(mth_sig_verif_types, sig); 1667 int nargs = mth_sig_verif_types.num_args(); 1668 int bci = bcs.bci(); 1669 if (opcode == INVOKEINTERFACE) { 1670 if ((_method.codeArray()[bci+3] & 0xff) != (nargs+1)) { 1671 verifyError("Inconsistent args count operand in invokeinterface"); 1672 } 1673 if ((_method.codeArray()[bci+4] & 0xff) != 0) { 1674 verifyError("Fourth operand byte of invokeinterface must be zero"); 1675 } 1676 } 1677 if (opcode == INVOKEDYNAMIC) { 1678 if ((_method.codeArray()[bci+3] & 0xff) != 0 || (_method.codeArray()[bci+4] & 0xff) != 0) { 1679 verifyError("Third and fourth operand bytes of invokedynamic must be zero"); 1680 } 1681 } 1682 if (method_name.charAt(0) == JVM_SIGNATURE_SPECIAL) { 1683 if (opcode != INVOKESPECIAL || 1684 !object_initializer_name.equals(method_name)) { 1685 verifyError("Illegal call to internal method"); 1686 } 1687 } else if (opcode == INVOKESPECIAL 1688 && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type) 1689 && !ref_class_type.equals(VerificationType.reference_type( 1690 current_class().superclassName()))) { 1691 1692 // We know it is not current class, direct superinterface or immediate superclass. That means it 1693 // could be: 1694 // - a totally unrelated class or interface 1695 // - an indirect superinterface 1696 // - an indirect superclass (including Object) 1697 // We use the assignability test to see if it is a superclass, or else an interface, and keep track 1698 // of the latter. Note that subtype can be true if we are dealing with an interface that is not actually 1699 // implemented as assignability treats all interfaces as Object. 1700 1701 boolean[] is_interface = {false}; // This can only be set true if the assignability check will return true 1702 // and we loaded the class. For any other "true" returns (e.g. same class 1703 // or Object) we either can't get here (same class already excluded above) 1704 // or we know it is not an interface (i.e. Object). 1705 boolean subtype = ref_class_type.is_reference_assignable_from(current_type(), this, is_interface); 1706 if (!subtype) { // Totally unrelated class 1707 verifyError("Bad invokespecial instruction: current class isn't assignable to reference class."); 1708 } else { 1709 // Indirect superclass (including Object), indirect interface, or unrelated interface. 1710 // Any interface use is an error. 1711 if (is_interface[0]) { 1712 verifyError("Bad invokespecial instruction: interface method to invoke is not in a direct superinterface."); 1713 } 1714 } 1715 1716 } 1717 ArrayList<VerificationType> sig_verif_types = mth_sig_verif_types.sig_verif_types(); 1718 if (sig_verif_types == null) verifyError("Missing signature's array of verification types"); 1719 for (int i = nargs - 1; i >= 0; i--) { // Run backwards 1720 current_frame.pop_stack(sig_verif_types.get(i)); 1721 } 1722 if (opcode != INVOKESTATIC && 1723 opcode != INVOKEDYNAMIC) { 1724 if (object_initializer_name.equals(method_name)) { // <init> method 1725 this_uninit = verify_invoke_init(bcs, index, ref_class_type, current_frame, 1726 code_length, in_try_block, this_uninit, cp, stackmap_table); 1727 } else { 1728 switch (opcode) { 1729 case INVOKESPECIAL -> 1730 current_frame.pop_stack(current_type()); 1731 case INVOKEVIRTUAL -> { 1732 VerificationType stack_object_type = 1733 current_frame.pop_stack(ref_class_type); 1734 if (current_type() != stack_object_type) { 1735 cp.classNameAt(cp.refClassIndexAt(index)); 1736 } 1737 } 1738 default -> { 1739 if (opcode != INVOKEINTERFACE) 1740 verifyError("Unexpected opcode encountered"); 1741 current_frame.pop_stack(ref_class_type); 1742 } 1743 } 1744 } 1745 } 1746 int sig_verif_types_len = sig_verif_types.size(); 1747 if (sig_verif_types_len > nargs) { // There's a return type 1748 if (object_initializer_name.equals(method_name)) { 1749 verifyError("Return type must be void in <init> method"); 1750 } 1751 1752 if (sig_verif_types_len > nargs + 2) verifyError("Signature verification types array return type is bogus"); 1753 for (int i = nargs; i < sig_verif_types_len; i++) { 1754 if (!(i == nargs || sig_verif_types.get(i).is_long2() || sig_verif_types.get(i).is_double2())) verifyError("Unexpected return verificationType"); 1755 current_frame.push_stack(sig_verif_types.get(i)); 1756 } 1757 } 1758 return this_uninit; 1759 } 1760 1761 VerificationType get_newarray_type(int index, int bci) { 1762 String[] from_bt = new String[] { 1763 null, null, null, null, "[Z", "[C", "[F", "[D", "[B", "[S", "[I", "[J", 1764 }; 1765 if (index < T_BOOLEAN.type || index > T_LONG.type) { 1766 verifyError("Illegal newarray instruction"); 1767 } 1768 String sig = from_bt[index]; 1769 return VerificationType.reference_type(sig); 1770 } 1771 1772 void verify_anewarray(int bci, int index, ConstantPoolWrapper cp, VerificationFrame current_frame) { 1773 verify_cp_class_type(bci, index, cp); 1774 current_frame.pop_stack(VerificationType.integer_type); 1775 VerificationType component_type = cp_index_to_type(index, cp); 1776 int length; 1777 String arr_sig_str; 1778 if (component_type.is_array()) { // it's an array 1779 String component_name = component_type.name(); 1780 length = component_name.length(); 1781 if (length > MAX_ARRAY_DIMENSIONS && 1782 component_name.charAt(MAX_ARRAY_DIMENSIONS - 1) == JVM_SIGNATURE_ARRAY) { 1783 verifyError("Illegal anewarray instruction, array has more than 255 dimensions"); 1784 } 1785 length++; 1786 arr_sig_str = String.format("%c%s", JVM_SIGNATURE_ARRAY, component_name); 1787 if (arr_sig_str.length() != length) verifyError("Unexpected number of characters in string"); 1788 } else { // it's an object or interface 1789 String component_name = component_type.name(); 1790 length = component_name.length() + 3; 1791 arr_sig_str = String.format("%c%c%s;", JVM_SIGNATURE_ARRAY, JVM_SIGNATURE_CLASS, component_name); 1792 if (arr_sig_str.length() != length) verifyError("Unexpected number of characters in string"); 1793 } 1794 VerificationType new_array_type = VerificationType.reference_type(arr_sig_str); 1795 current_frame.push_stack(new_array_type); 1796 } 1797 1798 void verify_iload(int index, VerificationFrame current_frame) { 1799 current_frame.get_local( 1800 index, VerificationType.integer_type); 1801 current_frame.push_stack( 1802 VerificationType.integer_type); 1803 } 1804 1805 void verify_lload(int index, VerificationFrame current_frame) { 1806 current_frame.get_local_2( 1807 index, VerificationType.long_type, 1808 VerificationType.long2_type); 1809 current_frame.push_stack_2( 1810 VerificationType.long_type, 1811 VerificationType.long2_type); 1812 } 1813 1814 void verify_fload(int index, VerificationFrame current_frame) { 1815 current_frame.get_local( 1816 index, VerificationType.float_type); 1817 current_frame.push_stack( 1818 VerificationType.float_type); 1819 } 1820 1821 void verify_dload(int index, VerificationFrame current_frame) { 1822 current_frame.get_local_2( 1823 index, VerificationType.double_type, 1824 VerificationType.double2_type); 1825 current_frame.push_stack_2( 1826 VerificationType.double_type, 1827 VerificationType.double2_type); 1828 } 1829 1830 void verify_aload(int index, VerificationFrame current_frame) { 1831 VerificationType type = current_frame.get_local( 1832 index, VerificationType.reference_check); 1833 current_frame.push_stack(type); 1834 } 1835 1836 void verify_istore(int index, VerificationFrame current_frame) { 1837 current_frame.pop_stack( 1838 VerificationType.integer_type); 1839 current_frame.set_local( 1840 index, VerificationType.integer_type); 1841 } 1842 1843 void verify_lstore(int index, VerificationFrame current_frame) { 1844 current_frame.pop_stack_2( 1845 VerificationType.long2_type, 1846 VerificationType.long_type); 1847 current_frame.set_local_2( 1848 index, VerificationType.long_type, 1849 VerificationType.long2_type); 1850 } 1851 1852 void verify_fstore(int index, VerificationFrame current_frame) { 1853 current_frame.pop_stack( 1854 VerificationType.float_type); 1855 current_frame.set_local( 1856 index, VerificationType.float_type); 1857 } 1858 1859 void verify_dstore(int index, VerificationFrame current_frame) { 1860 current_frame.pop_stack_2( 1861 VerificationType.double2_type, 1862 VerificationType.double_type); 1863 current_frame.set_local_2( 1864 index, VerificationType.double_type, 1865 VerificationType.double2_type); 1866 } 1867 1868 void verify_astore(int index, VerificationFrame current_frame) { 1869 VerificationType type = current_frame.pop_stack( 1870 VerificationType.reference_check); 1871 current_frame.set_local(index, type); 1872 } 1873 1874 void verify_iinc(int index, VerificationFrame current_frame) { 1875 VerificationType type = current_frame.get_local( 1876 index, VerificationType.integer_type); 1877 current_frame.set_local(index, type); 1878 } 1879 1880 void verify_return_value(VerificationType return_type, VerificationType type, int bci, VerificationFrame current_frame) { 1881 if (return_type.is_bogus()) { 1882 verifyError("Method does not expect a return value"); 1883 } 1884 boolean match = return_type.is_assignable_from(type, this); 1885 if (!match) { 1886 verifyError("Bad return type"); 1887 } 1888 } 1889 1890 private void dumpMethod() { 1891 if (_logger != null) ClassPrinter.toTree(_method.m, ClassPrinter.Verbosity.CRITICAL_ATTRIBUTES).toYaml(_logger); 1892 } 1893 1894 void verifyError(String msg) { 1895 dumpMethod(); 1896 throw new VerifyError(String.format("%s in %s::%s(%s) @%d %s", msg, _klass.thisClassName(), _method.name(), _method.parameters(), bci, errorContext).trim()); 1897 } 1898 1899 void verifyError(String msg, VerificationFrame from, VerificationFrame target) { 1900 dumpMethod(); 1901 throw new VerifyError(String.format("%s in %s::%s(%s) @%d %s%n while assigning %s%n to %s", msg, _klass.thisClassName(), _method.name(), _method.parameters(), bci, errorContext, from, target)); 1902 } 1903 1904 void classError(String msg) { 1905 dumpMethod(); 1906 throw new VerifyError(String.format("%s in %s::%s(%s)", msg, _klass.thisClassName(), _method.name(), _method.parameters())); 1907 } 1908 }