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 boolean verify_invoke_init(RawBytecodeHelper bcs, int ref_class_index, VerificationType ref_class_type,
1559 VerificationFrame current_frame, int code_length, boolean in_try_block,
1560 boolean this_uninit, ConstantPoolWrapper cp, VerificationTable stackmap_table) {
1561 int bci = bcs.bci();
1562 VerificationType type = current_frame.pop_stack(VerificationType.reference_check);
1563 if (type.is_uninitialized_this(this)) {
1564 String superk_name = current_class().superclassName();
1565 if (!current_class().thisClassName().equals(ref_class_type.name()) &&
1566 !superk_name.equals(ref_class_type.name())) {
1567 verifyError("Bad <init> method call");
1568 } else if (ref_class_type.name().equals(superk_name)) {
1569 // Strict final fields must be satisfied by this point
1570 if (!current_frame.verify_unset_fields_satisfied()) {
1571 current_frame.unsatisfied_strict_fields_error(current_class(), bci);
1572 }
1573 }
1574 if (in_try_block) {
1575 verify_exception_handler_targets(bci, true, current_frame, stackmap_table);
1576 }
1577 current_frame.initialize_object(type, current_type());
1578 this_uninit = true;
1579 } else if (type.is_uninitialized()) {
1580 int new_offset = type.bci(this);
1581 if (new_offset > (code_length - 3) || (_method.codeArray()[new_offset] & 0xff) != NEW) {
1582 verifyError("Expecting new instruction");
1583 }
1584 int new_class_index = bcs.getU2(new_offset + 1);
1585 verify_cp_class_type(bci, new_class_index, cp);
1586 VerificationType new_class_type = cp_index_to_type(
1587 new_class_index, cp);
1588 if (!new_class_type.equals(ref_class_type)) {
1589 verifyError("Call to wrong <init> method");
1590 }
1591 if (in_try_block) {
1592 verify_exception_handler_targets(bci, this_uninit, current_frame,
1593 stackmap_table);
1594 }
1595 current_frame.initialize_object(type, new_class_type);
1596 } else {
1597 verifyError("Bad operand type when invoking <init>");
1598 }
1599 return this_uninit;
1600 }
1601
1602 static boolean is_same_or_direct_interface(VerificationWrapper klass, VerificationType klass_type, VerificationType ref_class_type) {
1603 if (ref_class_type.equals(klass_type)) return true;
1604 for (String k_name : klass.interfaceNames()) {
1605 if (ref_class_type.equals(VerificationType.reference_type(k_name))) {
1606 return true;
1607 }
1608 }
1609 return false;
1610 }
1611
1612 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) {
1613 // Make sure the constant pool item is the right type
1614 int index = bcs.getIndexU2();
1615 int opcode = bcs.opcode();
1616 int types = 0;
1617 switch (opcode) {
1618 case INVOKEINTERFACE:
1619 types = 1 << JVM_CONSTANT_InterfaceMethodref;
1620 break;
1621 case INVOKEDYNAMIC:
1622 types = 1 << JVM_CONSTANT_InvokeDynamic;
1623 break;
1624 case INVOKESPECIAL:
1625 case INVOKESTATIC:
1626 types = (_klass.majorVersion() < STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION) ?
1627 (1 << JVM_CONSTANT_Methodref) :
1628 ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref));
1629 break;
1630 default:
1631 types = 1 << JVM_CONSTANT_Methodref;
1632 }
1633 verify_cp_type(bcs.bci(), index, cp, types);
1634 String method_name = cp.refNameAt(index);
1635 String method_sig = cp.refSignatureAt(index);
1636 if (!VerificationSignature.isValidMethodSignature(method_sig)) verifyError("Invalid method signature");
1637 VerificationType ref_class_type = null;
1638 if (opcode == INVOKEDYNAMIC) {
1639 if (_klass.majorVersion() < INVOKEDYNAMIC_MAJOR_VERSION) {
1640 classError(String.format("invokedynamic instructions not supported by this class file version (%d), class %s", _klass.majorVersion(), _klass.thisClassName()));
1641 }
1642 } else {
1643 ref_class_type = cp_ref_index_to_type(index, cp);
1644 }
1645 String sig = cp.refSignatureAt(index);
1646 sig_as_verification_types mth_sig_verif_types;
1647 ArrayList<VerificationType> verif_types = new ArrayList<>(10);
1648 mth_sig_verif_types = new sig_as_verification_types(verif_types);
1649 create_method_sig_entry(mth_sig_verif_types, sig);
1650 int nargs = mth_sig_verif_types.num_args();
1651 int bci = bcs.bci();
1652 if (opcode == INVOKEINTERFACE) {
1653 if ((_method.codeArray()[bci+3] & 0xff) != (nargs+1)) {
1654 verifyError("Inconsistent args count operand in invokeinterface");
1655 }
1656 if ((_method.codeArray()[bci+4] & 0xff) != 0) {
1657 verifyError("Fourth operand byte of invokeinterface must be zero");
1658 }
1659 }
1660 if (opcode == INVOKEDYNAMIC) {
1661 if ((_method.codeArray()[bci+3] & 0xff) != 0 || (_method.codeArray()[bci+4] & 0xff) != 0) {
1662 verifyError("Third and fourth operand bytes of invokedynamic must be zero");
1663 }
1664 }
1665 if (method_name.charAt(0) == JVM_SIGNATURE_SPECIAL) {
1666 if (opcode != INVOKESPECIAL ||
1667 !object_initializer_name.equals(method_name)) {
1668 verifyError("Illegal call to internal method");
1669 }
1670 } else if (opcode == INVOKESPECIAL
1671 && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type)
1672 && !ref_class_type.equals(VerificationType.reference_type(
1673 current_class().superclassName()))) {
1674
1675 // We know it is not current class, direct superinterface or immediate superclass. That means it
1676 // could be:
1677 // - a totally unrelated class or interface
1678 // - an indirect superinterface
1679 // - an indirect superclass (including Object)
1680 // We use the assignability test to see if it is a superclass, or else an interface, and keep track
1681 // of the latter. Note that subtype can be true if we are dealing with an interface that is not actually
1682 // implemented as assignability treats all interfaces as Object.
1683
1684 boolean[] is_interface = {false}; // This can only be set true if the assignability check will return true
1685 // and we loaded the class. For any other "true" returns (e.g. same class
1686 // or Object) we either can't get here (same class already excluded above)
1687 // or we know it is not an interface (i.e. Object).
1688 boolean subtype = ref_class_type.is_reference_assignable_from(current_type(), this, is_interface);
1689 if (!subtype) { // Totally unrelated class
1690 verifyError("Bad invokespecial instruction: current class isn't assignable to reference class.");
1691 } else {
1692 // Indirect superclass (including Object), indirect interface, or unrelated interface.
1693 // Any interface use is an error.
1694 if (is_interface[0]) {
1695 verifyError("Bad invokespecial instruction: interface method to invoke is not in a direct superinterface.");
1696 }
1697 }
1698
1699 }
1700 ArrayList<VerificationType> sig_verif_types = mth_sig_verif_types.sig_verif_types();
1701 if (sig_verif_types == null) verifyError("Missing signature's array of verification types");
1702 for (int i = nargs - 1; i >= 0; i--) { // Run backwards
1703 current_frame.pop_stack(sig_verif_types.get(i));
1704 }
1705 if (opcode != INVOKESTATIC &&
1706 opcode != INVOKEDYNAMIC) {
1707 if (object_initializer_name.equals(method_name)) { // <init> method
1708 this_uninit = verify_invoke_init(bcs, index, ref_class_type, current_frame,
1709 code_length, in_try_block, this_uninit, cp, stackmap_table);
1710 } else {
1711 switch (opcode) {
1712 case INVOKESPECIAL ->
1713 current_frame.pop_stack(current_type());
1714 case INVOKEVIRTUAL -> {
1715 VerificationType stack_object_type =
1716 current_frame.pop_stack(ref_class_type);
1717 if (current_type() != stack_object_type) {
1718 cp.classNameAt(cp.refClassIndexAt(index));
1719 }
1720 }
1721 default -> {
1722 if (opcode != INVOKEINTERFACE)
1723 verifyError("Unexpected opcode encountered");
1724 current_frame.pop_stack(ref_class_type);
1725 }
1726 }
1727 }
1728 }
1729 int sig_verif_types_len = sig_verif_types.size();
1730 if (sig_verif_types_len > nargs) { // There's a return type
1731 if (object_initializer_name.equals(method_name)) {
1732 verifyError("Return type must be void in <init> method");
1733 }
1734
1735 if (sig_verif_types_len > nargs + 2) verifyError("Signature verification types array return type is bogus");
1736 for (int i = nargs; i < sig_verif_types_len; i++) {
1737 if (!(i == nargs || sig_verif_types.get(i).is_long2() || sig_verif_types.get(i).is_double2())) verifyError("Unexpected return verificationType");
1738 current_frame.push_stack(sig_verif_types.get(i));
1739 }
1740 }
1741 return this_uninit;
1742 }
1743
1744 VerificationType get_newarray_type(int index, int bci) {
1745 String[] from_bt = new String[] {
1746 null, null, null, null, "[Z", "[C", "[F", "[D", "[B", "[S", "[I", "[J",
1747 };
1748 if (index < T_BOOLEAN.type || index > T_LONG.type) {
1749 verifyError("Illegal newarray instruction");
1750 }
1751 String sig = from_bt[index];
1752 return VerificationType.reference_type(sig);
1753 }
1754
1755 void verify_anewarray(int bci, int index, ConstantPoolWrapper cp, VerificationFrame current_frame) {
1756 verify_cp_class_type(bci, index, cp);
1757 current_frame.pop_stack(VerificationType.integer_type);
1758 VerificationType component_type = cp_index_to_type(index, cp);
1759 int length;
1760 String arr_sig_str;
1761 if (component_type.is_array()) { // it's an array
1762 String component_name = component_type.name();
1763 length = component_name.length();
1764 if (length > MAX_ARRAY_DIMENSIONS &&
1765 component_name.charAt(MAX_ARRAY_DIMENSIONS - 1) == JVM_SIGNATURE_ARRAY) {
1766 verifyError("Illegal anewarray instruction, array has more than 255 dimensions");
1767 }
1768 length++;
1769 arr_sig_str = String.format("%c%s", JVM_SIGNATURE_ARRAY, component_name);
1770 if (arr_sig_str.length() != length) verifyError("Unexpected number of characters in string");
1771 } else { // it's an object or interface
1772 String component_name = component_type.name();
1773 length = component_name.length() + 3;
1774 arr_sig_str = String.format("%c%c%s;", JVM_SIGNATURE_ARRAY, JVM_SIGNATURE_CLASS, component_name);
1775 if (arr_sig_str.length() != length) verifyError("Unexpected number of characters in string");
1776 }
1777 VerificationType new_array_type = VerificationType.reference_type(arr_sig_str);
1778 current_frame.push_stack(new_array_type);
1779 }
1780
1781 void verify_iload(int index, VerificationFrame current_frame) {
1782 current_frame.get_local(
1783 index, VerificationType.integer_type);
1784 current_frame.push_stack(
1785 VerificationType.integer_type);
1786 }
1787
1788 void verify_lload(int index, VerificationFrame current_frame) {
1789 current_frame.get_local_2(
1790 index, VerificationType.long_type,
1791 VerificationType.long2_type);
1792 current_frame.push_stack_2(
1793 VerificationType.long_type,
1794 VerificationType.long2_type);
1795 }
1796
1797 void verify_fload(int index, VerificationFrame current_frame) {
1798 current_frame.get_local(
1799 index, VerificationType.float_type);
1800 current_frame.push_stack(
1801 VerificationType.float_type);
1802 }
1803
1804 void verify_dload(int index, VerificationFrame current_frame) {
1805 current_frame.get_local_2(
1806 index, VerificationType.double_type,
1807 VerificationType.double2_type);
1808 current_frame.push_stack_2(
1809 VerificationType.double_type,
1810 VerificationType.double2_type);
1811 }
1812
1813 void verify_aload(int index, VerificationFrame current_frame) {
1814 VerificationType type = current_frame.get_local(
1815 index, VerificationType.reference_check);
1816 current_frame.push_stack(type);
1817 }
1818
1819 void verify_istore(int index, VerificationFrame current_frame) {
1820 current_frame.pop_stack(
1821 VerificationType.integer_type);
1822 current_frame.set_local(
1823 index, VerificationType.integer_type);
1824 }
1825
1826 void verify_lstore(int index, VerificationFrame current_frame) {
1827 current_frame.pop_stack_2(
1828 VerificationType.long2_type,
1829 VerificationType.long_type);
1830 current_frame.set_local_2(
1831 index, VerificationType.long_type,
1832 VerificationType.long2_type);
1833 }
1834
1835 void verify_fstore(int index, VerificationFrame current_frame) {
1836 current_frame.pop_stack(
1837 VerificationType.float_type);
1838 current_frame.set_local(
1839 index, VerificationType.float_type);
1840 }
1841
1842 void verify_dstore(int index, VerificationFrame current_frame) {
1843 current_frame.pop_stack_2(
1844 VerificationType.double2_type,
1845 VerificationType.double_type);
1846 current_frame.set_local_2(
1847 index, VerificationType.double_type,
1848 VerificationType.double2_type);
1849 }
1850
1851 void verify_astore(int index, VerificationFrame current_frame) {
1852 VerificationType type = current_frame.pop_stack(
1853 VerificationType.reference_check);
1854 current_frame.set_local(index, type);
1855 }
1856
1857 void verify_iinc(int index, VerificationFrame current_frame) {
1858 VerificationType type = current_frame.get_local(
1859 index, VerificationType.integer_type);
1860 current_frame.set_local(index, type);
1861 }
1862
1863 void verify_return_value(VerificationType return_type, VerificationType type, int bci, VerificationFrame current_frame) {
1864 if (return_type.is_bogus()) {
1865 verifyError("Method does not expect a return value");
1866 }
1867 boolean match = return_type.is_assignable_from(type, this);
1868 if (!match) {
1869 verifyError("Bad return type");
1870 }
1871 }
1872
1873 private void dumpMethod() {
1874 if (_logger != null) ClassPrinter.toTree(_method.m, ClassPrinter.Verbosity.CRITICAL_ATTRIBUTES).toYaml(_logger);
1875 }
1876
1877 void verifyError(String msg) {
1878 dumpMethod();
1879 throw new VerifyError(String.format("%s in %s::%s(%s) @%d %s", msg, _klass.thisClassName(), _method.name(), _method.parameters(), bci, errorContext).trim());
1880 }
1881
1882 void verifyError(String msg, VerificationFrame from, VerificationFrame target) {
1883 dumpMethod();
1884 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));
1885 }
1886
1887 void classError(String msg) {
1888 dumpMethod();
1889 throw new VerifyError(String.format("%s in %s::%s(%s)", msg, _klass.thisClassName(), _method.name(), _method.parameters()));
1890 }
1891 }