< 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

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














1504                 }
1505                 is_assignable = target_class_type.is_assignable_from(stack_object_type, this);
1506                 if (!is_assignable) {
1507                     verifyError("Bad type on operand stack in putfield");
1508                 }
1509             }
1510             default -> verifyError("Should not reach here");
1511         }
1512     }
1513 
1514     boolean verify_invoke_init(RawBytecodeHelper bcs, int ref_class_index, VerificationType ref_class_type,
1515             VerificationFrame current_frame, int code_length, boolean in_try_block,
1516             boolean this_uninit, ConstantPoolWrapper cp, VerificationTable stackmap_table) {
1517         int bci = bcs.bci();
1518         VerificationType type = current_frame.pop_stack(VerificationType.reference_check);
1519         if (type.is_uninitialized_this(this)) {
1520             String superk_name = current_class().superclassName();
1521             if (!current_class().thisClassName().equals(ref_class_type.name()) &&
1522                     !superk_name.equals(ref_class_type.name())) {
1523                 verifyError("Bad <init> method call");





1524             }
1525             if (in_try_block) {
1526                 verify_exception_handler_targets(bci, true, current_frame, stackmap_table);
1527             }
1528             current_frame.initialize_object(type, current_type());
1529             this_uninit = true;
1530         } else if (type.is_uninitialized()) {
1531             int new_offset = type.bci(this);
1532             if (new_offset > (code_length - 3) || (_method.codeArray()[new_offset] & 0xff) != NEW) {
1533                 verifyError("Expecting new instruction");
1534             }
1535             int new_class_index = bcs.getU2(new_offset + 1);
1536             verify_cp_class_type(bci, new_class_index, cp);
1537             VerificationType new_class_type = cp_index_to_type(
1538                 new_class_index, cp);
1539             if (!new_class_type.equals(ref_class_type)) {
1540                 verifyError("Call to wrong <init> method");
1541             }
1542             if (in_try_block) {
1543                 verify_exception_handler_targets(bci, this_uninit, current_frame,

   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 java.lang.classfile.FieldModel;
  31 import java.lang.classfile.constantpool.NameAndTypeEntry;
  32 import java.lang.constant.ConstantDescs;
  33 import java.lang.reflect.AccessFlag;
  34 import java.util.ArrayList;
  35 import java.util.Collections;
  36 import java.util.HashSet;
  37 import java.util.List;
  38 import java.util.Set;
  39 import java.util.function.Consumer;
  40 
  41 import jdk.internal.classfile.components.ClassPrinter;
  42 import jdk.internal.classfile.impl.ClassHierarchyImpl;
  43 import jdk.internal.classfile.impl.RawBytecodeHelper;
  44 import jdk.internal.classfile.impl.TemporaryConstantPool;
  45 import jdk.internal.classfile.impl.Util;
  46 import jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType;
  47 import jdk.internal.classfile.impl.verifier.VerificationWrapper.ConstantPoolWrapper;
  48 
  49 import static jdk.internal.classfile.impl.RawBytecodeHelper.*;
  50 import static jdk.internal.classfile.impl.verifier.VerificationFrame.FLAG_THIS_UNINIT;
  51 import static jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType.T_BOOLEAN;
  52 import static jdk.internal.classfile.impl.verifier.VerificationSignature.BasicType.T_LONG;
  53 
  54 /// VerifierImpl performs selected checks and verifications of the class file
  55 /// format according to {@jvms 4.8 Format Checking},
  56 /// {@jvms 4.9 Constraints on Java Virtual Machine code},
  57 /// {@jvms 4.10 Verification of class Files} and {@jvms 6.5 Instructions}
  58 ///
  59 /// From `verifier.cpp`.
  60 public final class VerifierImpl {
  61     static final int
  62             JVM_CONSTANT_Utf8                   = 1,
  63             JVM_CONSTANT_Unicode                = 2,
  64             JVM_CONSTANT_Integer                = 3,
  65             JVM_CONSTANT_Float                  = 4,

  97     static final String java_lang_Object = "java/lang/Object";
  98     static final String java_lang_invoke_MethodType = "java/lang/invoke/MethodType";
  99     static final String java_lang_Throwable = "java/lang/Throwable";
 100     static final String java_lang_Class = "java/lang/Class";
 101 
 102     String errorContext = "";
 103     private int bci;
 104 
 105     static void log_info(Consumer<String> logger, String messageFormat, Object... args) {
 106         if (logger != null) logger.accept(String.format(messageFormat + "%n", args));
 107     }
 108     private final Consumer<String> _logger;
 109     void log_info(String messageFormat, Object... args) {
 110         log_info(_logger, messageFormat, args);
 111     }
 112 
 113 
 114     static final int STACKMAP_ATTRIBUTE_MAJOR_VERSION = 50;
 115     static final int INVOKEDYNAMIC_MAJOR_VERSION = 51;
 116     static final int NOFAILOVER_MAJOR_VERSION = 51;
 117     static final int VALUE_TYPES_MAJOR_VERSION = Util.VALUE_OBJECTS_MAJOR;
 118     static final int MAX_CODE_SIZE = 65535;
 119 
 120     public static List<VerifyError> verify(ClassModel classModel, Consumer<String> logger) {
 121         return verify(classModel, ClassHierarchyResolver.defaultResolver(), logger);
 122     }
 123 
 124     public static List<VerifyError> verify(ClassModel classModel, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) {
 125         String clsName = classModel.thisClass().asInternalName();
 126         log_info(logger, "Start class verification for: %s", clsName);
 127         try {
 128             var klass = new VerificationWrapper(classModel);
 129             var errors = new ArrayList<VerifyError>();
 130             errors.addAll(new ParserVerifier(classModel).verify());
 131             if (is_eligible_for_verification(klass)) {
 132                 if (klass.majorVersion() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
 133                     var verifierErrors = new VerifierImpl(klass, classHierarchyResolver, logger).verify_class();
 134                     if (!verifierErrors.isEmpty() && klass.majorVersion() < NOFAILOVER_MAJOR_VERSION) {
 135                         log_info(logger, "Fail over class verification to old verifier for: %s", klass.thisClassName());
 136                         errors.addAll(inference_verify(klass));
 137                     } else {

 235                 verifyError("Should not reach here");
 236                 return 1;
 237         }
 238     }
 239 
 240     private static final int NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION = 51;
 241     private static final int STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION = 52;
 242     private static final int MAX_ARRAY_DIMENSIONS = 255;
 243 
 244     VerifierImpl(VerificationWrapper klass, ClassHierarchyResolver classHierarchyResolver, Consumer<String> logger) {
 245         _klass = klass;
 246         _class_hierarchy = new ClassHierarchyImpl(classHierarchyResolver);
 247         _this_type = VerificationType.reference_type(klass.thisClassName());
 248         _logger = logger;
 249     }
 250 
 251     private VerificationType object_type() {
 252         return VerificationType.reference_type(java_lang_Object);
 253     }
 254 
 255     static boolean supports_strict_fields(VerificationWrapper klass) {
 256         int ver = klass.majorVersion();
 257         return ver > VALUE_TYPES_MAJOR_VERSION ||
 258                 (ver == VALUE_TYPES_MAJOR_VERSION && klass.clm.minorVersion() == ClassFile.PREVIEW_MINOR_VERSION);
 259     }
 260 
 261     List<VerifyError> verify_class() {
 262         log_info("Verifying class %s with new format", _klass.thisClassName());
 263         var errors = new ArrayList<VerifyError>();
 264         for (VerificationWrapper.MethodWrapper m : _klass.methods()) {
 265             if (m.isNative() || m.isAbstract() || m.isBridge()) {
 266                 continue;
 267             }
 268             verify_method(m, errors);
 269         }
 270         return errors;
 271     }
 272 
 273     void translate_signature(String method_sig, sig_as_verification_types sig_verif_types) {
 274         var sig_stream = new VerificationSignature(method_sig, true, this);
 275         VerificationType[] sig_type = new VerificationType[2];
 276         int sig_i = 0;
 277         ArrayList<VerificationType> verif_types = sig_verif_types.sig_verif_types();
 278         while (!sig_stream.atReturnType()) {
 279             int n = change_sig_to_verificationType(sig_stream, sig_type, 0);
 280             if (n > 2) verifyError("Unexpected signature type");

 302         try {
 303             verify_method(m);
 304         } catch (VerifyError err) {
 305             errorsCollector.add(err);
 306         } catch (Error | Exception e) {
 307             errorsCollector.add(new VerifyError(e.toString()));
 308         }
 309     }
 310 
 311     @SuppressWarnings("fallthrough")
 312     void verify_method(VerificationWrapper.MethodWrapper m) {
 313         _method = m;
 314         log_info(_logger, "Verifying method %s%s", m.name(), m.descriptor());
 315         byte[] codeArray = m.codeArray();
 316         if (codeArray == null) verifyError("Missing Code attribute");
 317         int max_locals = m.maxLocals();
 318         int max_stack = m.maxStack();
 319         byte[] stackmap_data = m.stackMapTableRawData();
 320         var cp = m.constantPool();
 321         if (!VerificationSignature.isValidMethodSignature(m.descriptor())) verifyError("Invalid method signature");
 322 
 323         // Collect the initial strict instance fields
 324         Set<NameAndTypeEntry> strict_fields = new HashSet<>();
 325         if (m.name().equals(ConstantDescs.INIT_NAME)) {
 326             for (var fs : current_class().clm.fields()) {
 327                 if (fs.flags().has(AccessFlag.STRICT_INIT) && !fs.flags().has(AccessFlag.STATIC)) {
 328                     var new_field = TemporaryConstantPool.INSTANCE.nameAndTypeEntry(fs.fieldName(), fs.fieldType());
 329                     strict_fields.add(new_field);
 330                 }
 331             }
 332         }
 333 
 334         VerificationFrame current_frame = new VerificationFrame(max_locals, max_stack, strict_fields, this);
 335         VerificationType return_type = current_frame.set_locals_from_arg(m, current_type());
 336         int stackmap_index = 0;
 337         int code_length = m.codeLength();
 338         if (code_length < 1 || code_length > MAX_CODE_SIZE) {
 339             verifyError(String.format("Invalid method Code length %d", code_length));
 340         }
 341         var code = RawBytecodeHelper.of(codeArray);
 342         byte[] code_data = generate_code_data(code);
 343         int ex_minmax[] = new int[] {code_length, -1};
 344         verify_exception_handler_table(code_length, code_data, ex_minmax);
 345         verify_local_variable_table(code_length, code_data);
 346 
 347         var reader = new VerificationTable.StackMapReader(stackmap_data, code_data, code_length, current_frame,
 348                 (char) max_locals, (char) max_stack, strict_fields, cp, this);
 349         VerificationTable stackmap_table = new VerificationTable(reader, cp, this);
 350 
 351         var bcs = code.start();
 352         boolean no_control_flow = false;
 353         int opcode;
 354         while (bcs.next()) {
 355             opcode = bcs.opcode();
 356             bci = bcs.bci();
 357             current_frame.set_offset(bci);
 358             current_frame.set_mark();
 359             stackmap_index = verify_stackmap_table(stackmap_index, bci, current_frame, stackmap_table, no_control_flow);
 360             boolean this_uninit = false;
 361             boolean verified_exc_handlers = false;
 362             {
 363                 int index;
 364                 int target;
 365                 VerificationType type, type2 = null;
 366                 VerificationType atype;
 367                 if (bcs.isWide()) {
 368                     if (opcode != IINC && opcode != ILOAD

1508                 }
1509             }
1510             case PUTSTATIC ->  {
1511                 for (int i = n - 1; i >= 0; i--) {
1512                     current_frame.pop_stack(field_type[i]);
1513                 }
1514             }
1515             case GETFIELD ->  {
1516                 stack_object_type = current_frame.pop_stack(
1517                     target_class_type);
1518                 // 8270398 Not applicable here
1519                 for (int i = 0; i < n; i++) {
1520                     current_frame.push_stack(field_type[i]);
1521                 }
1522             }
1523             case PUTFIELD ->  {
1524                 for (int i = n - 1; i >= 0; i--) {
1525                     current_frame.pop_stack(field_type[i]);
1526                 }
1527                 stack_object_type = current_frame.pop_stack();
1528                 FieldModel fd = _klass.findField(field_name, field_sig);
1529                 boolean is_local_field = fd != null &&
1530                         target_class_type.equals(current_type());
1531                 if (stack_object_type.is_uninitialized_this(this)) {
1532                     if (is_local_field) {
1533                         // Set the type to the current type so the is_assignable check passes.
1534                         stack_object_type = current_type();
1535 
1536                         if (fd.flags().has(AccessFlag.STRICT_INIT)) {
1537                             current_frame.satisfy_unset_field(fd.fieldName(), fd.fieldType());
1538                         }
1539                     }
1540                 } else if (supports_strict_fields(_klass)) {
1541                     // `strict` fields are not writable, but only local fields produce verification errors
1542                     if (is_local_field && fd.flags().has(AccessFlag.STRICT_INIT) && fd.flags().has(AccessFlag.FINAL)) {
1543                         verifyError("Bad code %d %s".formatted(bci,
1544                                 "Illegal use of putfield on a strict field: %s:%s".formatted(fd.fieldName(), fd.fieldType())));
1545                     }
1546                 }
1547                 is_assignable = target_class_type.is_assignable_from(stack_object_type, this);
1548                 if (!is_assignable) {
1549                     verifyError("Bad type on operand stack in putfield");
1550                 }
1551             }
1552             default -> verifyError("Should not reach here");
1553         }
1554     }
1555 
1556     boolean verify_invoke_init(RawBytecodeHelper bcs, int ref_class_index, VerificationType ref_class_type,
1557             VerificationFrame current_frame, int code_length, boolean in_try_block,
1558             boolean this_uninit, ConstantPoolWrapper cp, VerificationTable stackmap_table) {
1559         int bci = bcs.bci();
1560         VerificationType type = current_frame.pop_stack(VerificationType.reference_check);
1561         if (type.is_uninitialized_this(this)) {
1562             String superk_name = current_class().superclassName();
1563             if (!current_class().thisClassName().equals(ref_class_type.name()) &&
1564                     !superk_name.equals(ref_class_type.name())) {
1565                 verifyError("Bad <init> method call");
1566             } else if (ref_class_type.name().equals(superk_name)) {
1567                 // Strict final fields must be satisfied by this point
1568                 if (!current_frame.verify_unset_fields_satisfied()) {
1569                     current_frame.unsatisfied_strict_fields_error(current_class(), bci);
1570                 }
1571             }
1572             if (in_try_block) {
1573                 verify_exception_handler_targets(bci, true, current_frame, stackmap_table);
1574             }
1575             current_frame.initialize_object(type, current_type());
1576             this_uninit = true;
1577         } else if (type.is_uninitialized()) {
1578             int new_offset = type.bci(this);
1579             if (new_offset > (code_length - 3) || (_method.codeArray()[new_offset] & 0xff) != NEW) {
1580                 verifyError("Expecting new instruction");
1581             }
1582             int new_class_index = bcs.getU2(new_offset + 1);
1583             verify_cp_class_type(bci, new_class_index, cp);
1584             VerificationType new_class_type = cp_index_to_type(
1585                 new_class_index, cp);
1586             if (!new_class_type.equals(ref_class_type)) {
1587                 verifyError("Call to wrong <init> method");
1588             }
1589             if (in_try_block) {
1590                 verify_exception_handler_targets(bci, this_uninit, current_frame,
< prev index next >