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