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