< prev index next >

src/java.base/share/classes/jdk/internal/classfile/impl/verifier/VerifierImpl.java

Print this page

   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.ClassHierarchyResolver;
  28 import java.lang.classfile.ClassModel;
  29 import jdk.internal.classfile.components.ClassPrinter;





  30 import java.util.ArrayList;
  31 import java.util.Collections;

  32 import java.util.List;


  33 import java.util.function.Consumer;
  34 
  35 import jdk.internal.classfile.impl.ClassHierarchyImpl;
  36 import jdk.internal.classfile.impl.RawBytecodeHelper;


  37 import jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType;
  38 import jdk.internal.classfile.impl.verifier.VerificationWrapper.ConstantPoolWrapper;
  39 
  40 import static jdk.internal.classfile.impl.RawBytecodeHelper.*;
  41 import static jdk.internal.classfile.impl.verifier.VerificationFrame.FLAG_THIS_UNINIT;
  42 import static jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType.T_BOOLEAN;
  43 import static jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType.T_LONG;
  44 
  45 /// VerifierImpl performs selected checks and verifications of the class file
  46 /// format according to {@jvms 4.8 Format Checking},
  47 /// {@jvms 4.9 Constraints on Java Virtual Machine code},
  48 /// {@jvms 4.10 Verification of class Files} and {@jvms 6.5 Instructions}
  49 ///
  50 /// From `verifier.cpp`.
  51 public final class VerifierImpl {
  52     static final int
  53             JVM_CONSTANT_Utf8                   = 1,
  54             JVM_CONSTANT_Unicode                = 2,
  55             JVM_CONSTANT_Integer                = 3,
  56             JVM_CONSTANT_Float                  = 4,

  88     static final String java_lang_Object = "java/lang/Object";
  89     static final String java_lang_invoke_MethodType = "java/lang/invoke/MethodType";
  90     static final String java_lang_Throwable = "java/lang/Throwable";
  91     static final String java_lang_Class = "java/lang/Class";
  92 
  93     String errorContext = "";
  94     private int bci;
  95 
  96     static void log_info(Consumer<String> logger, String messageFormat, Object... args) {
  97         if (logger != null) logger.accept(String.format(messageFormat + "%n", args));
  98     }
  99     private final Consumer<String> _logger;
 100     void log_info(String messageFormat, Object... args) {
 101         log_info(_logger, messageFormat, args);
 102     }
 103 
 104 
 105     static final int STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50;
 106     static final int INVOKEDYNAMIC_MAJOR_VERSION = 51;
 107     static final int NOFAILOVER_MAJOR_VERSION = 51;

 108     static final int MAX_CODE_SIZE = 65535;
 109 
 110     public static List<VerifyError> verify(ClassModel classModel, Consumer<String> logger) {
 111         return verify(classModel, ClassHierarchyResolver.defaultResolver(), logger);
 112     }
 113 
 114     public static List<VerifyError> verify(ClassModel classModel, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) {
 115         String clsName = classModel.thisClass().asInternalName();
 116         log_info(logger, "Start class verification for: %s", clsName);
 117         try {
 118             var klass = new VerificationWrapper(classModel);
 119             var errors = new ArrayList<VerifyError>();
 120             errors.addAll(new ParserVerifier(classModel).verify());
 121             if (is_eligible_for_verification(klass)) {
 122                 if (klass.majorVersion() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
 123                     var verifierErrors = new VerifierImpl(klass, classHierarchyResolver, logger).verify_class();
 124                     if (!verifierErrors.isEmpty() && klass.majorVersion() < NOFAILOVER_MAJOR_VERSION) {
 125                         log_info(logger, "Fail over class verification to old verifier for: %s", klass.thisClassName());
 126                         errors.addAll(inference_verify(klass));
 127                     } else {

 225                 verifyError("Should not reach here");
 226                 return 1;
 227         }
 228     }
 229 
 230     private static final int NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION = 51;
 231     private static final int STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION = 52;
 232     private static final int MAX_ARRAY_DIMENSIONS = 255;
 233 
 234     VerifierImpl(VerificationWrapper klass, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) {
 235         _klass = klass;
 236         _class_hierarchy = new ClassHierarchyImpl(classHierarchyResolver);
 237         _this_type = VerificationType.reference_type(klass.thisClassName());
 238         _logger = logger;
 239     }
 240 
 241     private VerificationType object_type() {
 242         return VerificationType.reference_type(java_lang_Object);
 243     }
 244 






 245     List<VerifyError> verify_class() {
 246         log_info("Verifying class %s with new format", _klass.thisClassName());
 247         var errors = new ArrayList<VerifyError>();
 248         for (VerificationWrapper.MethodWrapper m : _klass.methods()) {
 249             if (m.isNative() || m.isAbstract() || m.isBridge()) {
 250                 continue;
 251             }
 252             verify_method(m, errors);
 253         }
 254         return errors;
 255     }
 256 
 257     void translate_signature(String method_sig, sig_as_verification_types sig_verif_types) {
 258         var sig_stream = new VerificationSignature(method_sig, true, this);
 259         VerificationType[] sig_type = new VerificationType[2];
 260         int sig_i = 0;
 261         ArrayList<VerificationType> verif_types = sig_verif_types.sig_verif_types();
 262         while (!sig_stream.atReturnType()) {
 263             int n = change_sig_to_verificationType(sig_stream, sig_type, 0);
 264             if (n > 2) verifyError("Unexpected signature type");

 286         try {
 287             verify_method(m);
 288         } catch (VerifyError err) {
 289             errorsCollector.add(err);
 290         } catch (Error | Exception e) {
 291             errorsCollector.add(new VerifyError(e.toString()));
 292         }
 293     }
 294 
 295     @SuppressWarnings("fallthrough")
 296     void verify_method(VerificationWrapper.MethodWrapper m) {
 297         _method = m;
 298         log_info(_logger, "Verifying method %s%s", m.name(), m.descriptor());
 299         byte[] codeArray = m.codeArray();
 300         if (codeArray == null) verifyError("Missing Code attribute");
 301         int max_locals = m.maxLocals();
 302         int max_stack = m.maxStack();
 303         byte[] stackmap_data = m.stackMapTableRawData();
 304         var cp = m.constantPool();
 305         if (!VerificationSignature.isValidMethodSignature(m.descriptor())) verifyError("Invalid method signature");
 306         VerificationFrame current_frame = new VerificationFrame(max_locals, max_stack, this);












 307         VerificationType return_type = current_frame.set_locals_from_arg(m, current_type());
 308         int stackmap_index = 0;
 309         int code_length = m.codeLength();
 310         if (code_length < 1 || code_length > MAX_CODE_SIZE) {
 311             verifyError(String.format("Invalid method Code length %d", code_length));
 312         }
 313         var code = RawBytecodeHelper.of(codeArray);
 314         byte[] code_data = generate_code_data(code);
 315         int ex_minmax[] = new int[] {code_length, -1};
 316         verify_exception_handler_table(code_length, code_data, ex_minmax);
 317         verify_local_variable_table(code_length, code_data);
 318 
 319         var reader = new VerificationTable.StackMapReader(stackmap_data, code_data, code_length, current_frame,
 320                 (char) max_locals, (char) max_stack, cp, this);
 321         VerificationTable stackmap_table = new VerificationTable(reader, cp, this);
 322 
 323         var bcs = code.start();
 324         boolean no_control_flow = false;
 325         int opcode;
 326         while (bcs.next()) {
 327             opcode = bcs.opcode();
 328             bci = bcs.bci();
 329             current_frame.set_offset(bci);
 330             current_frame.set_mark();
 331             stackmap_index = verify_stackmap_table(stackmap_index, bci, current_frame, stackmap_table, no_control_flow);
 332             boolean this_uninit = false;
 333             boolean verified_exc_handlers = false;
 334             {
 335                 int index;
 336                 int target;
 337                 VerificationType type, type2 = null;
 338                 VerificationType atype;
 339                 if (bcs.isWide()) {
 340                     if (opcode != IINC && opcode != ILOAD

1030                     case IF_ICMPGE:
1031                     case IF_ICMPGT:
1032                     case IF_ICMPLE:
1033                         current_frame.pop_stack(
1034                             VerificationType.integer_type);
1035                         // fall through
1036                     case IFEQ:
1037                     case IFNE:
1038                     case IFLT:
1039                     case IFGE:
1040                     case IFGT:
1041                     case IFLE:
1042                         current_frame.pop_stack(
1043                             VerificationType.integer_type);
1044                         target = bcs.dest();
1045                         stackmap_table.check_jump_target(
1046                             current_frame, target);
1047                         no_control_flow = false; break;
1048                     case IF_ACMPEQ :
1049                     case IF_ACMPNE :
1050                         current_frame.pop_stack(
1051                             VerificationType.reference_check);
1052                         // fall through
1053                     case IFNULL :
1054                     case IFNONNULL :
1055                         current_frame.pop_stack(
1056                             VerificationType.reference_check);
1057                         target = bcs.dest();
1058                         stackmap_table.check_jump_target
1059                             (current_frame, target);
1060                         no_control_flow = false; break;
1061                     case GOTO :
1062                         target = bcs.dest();
1063                         stackmap_table.check_jump_target(
1064                             current_frame, target);
1065                         no_control_flow = true; break;
1066                     case GOTO_W :
1067                         target = bcs.destW();
1068                         stackmap_table.check_jump_target(
1069                             current_frame, target);
1070                         no_control_flow = true; break;
1071                     case TABLESWITCH :
1072                     case LOOKUPSWITCH :
1073                         verify_switch(
1074                             bcs, code_length, code_data, current_frame,
1075                             stackmap_table);
1076                         no_control_flow = true; break;

1482                 }
1483             }
1484             case PUTSTATIC ->  {
1485                 for (int i = n - 1; i >= 0; i--) {
1486                     current_frame.pop_stack(field_type[i]);
1487                 }
1488             }
1489             case GETFIELD ->  {
1490                 stack_object_type = current_frame.pop_stack(
1491                     target_class_type);
1492                 // 8270398 Not applicable here
1493                 for (int i = 0; i < n; i++) {
1494                     current_frame.push_stack(field_type[i]);
1495                 }
1496             }
1497             case PUTFIELD ->  {
1498                 for (int i = n - 1; i >= 0; i--) {
1499                     current_frame.pop_stack(field_type[i]);
1500                 }
1501                 stack_object_type = current_frame.pop_stack();
1502                 if (stack_object_type.is_uninitialized_this(this) &&
1503                         target_class_type.equals(current_type()) &&
1504                         _klass.findField(field_name, field_sig)) {
1505                     stack_object_type = current_type();














1506                 }
1507                 is_assignable = target_class_type.is_assignable_from(stack_object_type, this);
1508                 if (!is_assignable) {
1509                     verifyError("Bad type on operand stack in putfield");
1510                 }
1511             }
1512             default -> verifyError("Should not reach here");
1513         }
1514     }
1515 
1516     // Return TRUE if all code paths starting with start_bc_offset end in
1517     // bytecode athrow or loop.
1518     boolean ends_in_athrow(int start_bc_offset) {
1519         log_info("unimplemented VerifierImpl.ends_in_athrow");
1520         return true;
1521     }
1522 
1523     boolean verify_invoke_init(RawBytecodeHelper bcs, int ref_class_index, VerificationType ref_class_type,
1524             VerificationFrame current_frame, int code_length, boolean in_try_block,
1525             boolean this_uninit, ConstantPoolWrapper cp, VerificationTable stackmap_table) {
1526         int bci = bcs.bci();
1527         VerificationType type = current_frame.pop_stack(VerificationType.reference_check);
1528         if (type.is_uninitialized_this(this)) {
1529             String superk_name = current_class().superclassName();
1530             if (!current_class().thisClassName().equals(ref_class_type.name()) &&
1531                     !superk_name.equals(ref_class_type.name())) {
1532                 verifyError("Bad <init> method call");





1533             }
1534             if (in_try_block) {
1535                 for(var exhandler : _method.exceptionTable()) {
1536                     int start_pc = exhandler[0];
1537                     int end_pc = exhandler[1];
1538 
1539                     if (bci >= start_pc && bci < end_pc) {
1540                         if (!ends_in_athrow(exhandler[2])) {
1541                             verifyError("Bad <init> method call from after the start of a try block");
1542                         }
1543                     }
1544                 }
1545                 verify_exception_handler_targets(bci, true, current_frame, stackmap_table);
1546             }
1547             current_frame.initialize_object(type, current_type());
1548             this_uninit = true;
1549         } else if (type.is_uninitialized()) {
1550             int new_offset = type.bci(this);
1551             if (new_offset > (code_length - 3) || (_method.codeArray()[new_offset] & 0xff) != NEW) {
1552                 verifyError("Expecting new instruction");

   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,

  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 {

 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");

 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

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;

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");
< prev index next >