in src/java.base/share/classes/jdk/internal/classfile/impl/verifier/VerifierImpl.java [296:1227]
void verify_method(VerificationWrapper.MethodWrapper m) {
_method = m;
log_info(_logger, "Verifying method %s%s", m.name(), m.descriptor());
byte[] codeArray = m.codeArray();
if (codeArray == null) verifyError("Missing Code attribute");
int max_locals = m.maxLocals();
int max_stack = m.maxStack();
byte[] stackmap_data = m.stackMapTableRawData();
var cp = m.constantPool();
if (!VerificationSignature.isValidMethodSignature(m.descriptor())) verifyError("Invalid method signature");
VerificationFrame current_frame = new VerificationFrame(max_locals, max_stack, this);
VerificationType return_type = current_frame.set_locals_from_arg(m, current_type());
int stackmap_index = 0;
int code_length = m.codeLength();
if (code_length < 1 || code_length > MAX_CODE_SIZE) {
verifyError(String.format("Invalid method Code length %d", code_length));
}
var code = RawBytecodeHelper.of(codeArray);
byte[] code_data = generate_code_data(code);
int ex_minmax[] = new int[] {code_length, -1};
verify_exception_handler_table(code_length, code_data, ex_minmax);
verify_local_variable_table(code_length, code_data);
var reader = new VerificationTable.StackMapReader(stackmap_data, code_data, code_length, current_frame,
(char) max_locals, (char) max_stack, cp, this);
VerificationTable stackmap_table = new VerificationTable(reader, cp, this);
var bcs = code.start();
boolean no_control_flow = false;
int opcode;
while (bcs.next()) {
opcode = bcs.opcode();
bci = bcs.bci();
current_frame.set_offset(bci);
current_frame.set_mark();
stackmap_index = verify_stackmap_table(stackmap_index, bci, current_frame, stackmap_table, no_control_flow);
boolean this_uninit = false;
boolean verified_exc_handlers = false;
{
int index;
int target;
VerificationType type, type2 = null;
VerificationType atype;
if (bcs.isWide()) {
if (opcode != IINC && opcode != ILOAD
&& opcode != ALOAD && opcode != LLOAD
&& opcode != ISTORE && opcode != ASTORE
&& opcode != LSTORE && opcode != FLOAD
&& opcode != DLOAD && opcode != FSTORE
&& opcode != DSTORE) {
verifyError("Bad wide instruction");
}
}
if (VerificationBytecodes.is_store_into_local(opcode) && bci >= ex_minmax[0] && bci < ex_minmax[1]) {
verify_exception_handler_targets(bci, this_uninit, current_frame, stackmap_table);
verified_exc_handlers = true;
}
switch (opcode) {
case NOP :
no_control_flow = false; break;
case ACONST_NULL :
current_frame.push_stack(
VerificationType.null_type);
no_control_flow = false; break;
case ICONST_M1 :
case ICONST_0 :
case ICONST_1 :
case ICONST_2 :
case ICONST_3 :
case ICONST_4 :
case ICONST_5 :
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case LCONST_0 :
case LCONST_1 :
current_frame.push_stack_2(
VerificationType.long_type,
VerificationType.long2_type);
no_control_flow = false; break;
case FCONST_0 :
case FCONST_1 :
case FCONST_2 :
current_frame.push_stack(
VerificationType.float_type);
no_control_flow = false; break;
case DCONST_0 :
case DCONST_1 :
current_frame.push_stack_2(
VerificationType.double_type,
VerificationType.double2_type);
no_control_flow = false; break;
case SIPUSH :
case BIPUSH :
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case LDC :
verify_ldc(
opcode, bcs.getIndexU1(), current_frame,
cp, bci);
no_control_flow = false; break;
case LDC_W :
case LDC2_W :
verify_ldc(
opcode, bcs.getIndexU2(), current_frame,
cp, bci);
no_control_flow = false; break;
case ILOAD :
verify_iload(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case ILOAD_0 :
case ILOAD_1 :
case ILOAD_2 :
case ILOAD_3 :
index = opcode - ILOAD_0;
verify_iload(index, current_frame);
no_control_flow = false; break;
case LLOAD :
verify_lload(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case LLOAD_0 :
case LLOAD_1 :
case LLOAD_2 :
case LLOAD_3 :
index = opcode - LLOAD_0;
verify_lload(index, current_frame);
no_control_flow = false; break;
case FLOAD :
verify_fload(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case FLOAD_0 :
case FLOAD_1 :
case FLOAD_2 :
case FLOAD_3 :
index = opcode - FLOAD_0;
verify_fload(index, current_frame);
no_control_flow = false; break;
case DLOAD :
verify_dload(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case DLOAD_0 :
case DLOAD_1 :
case DLOAD_2 :
case DLOAD_3 :
index = opcode - DLOAD_0;
verify_dload(index, current_frame);
no_control_flow = false; break;
case ALOAD :
verify_aload(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case ALOAD_0 :
case ALOAD_1 :
case ALOAD_2 :
case ALOAD_3 :
index = opcode - ALOAD_0;
verify_aload(index, current_frame);
no_control_flow = false; break;
case IALOAD :
type = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_int_array()) {
verifyError("Bad type");
}
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case BALOAD :
type = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_bool_array() && !atype.is_byte_array()) {
verifyError("Bad type");
}
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case CALOAD :
type = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_char_array()) {
verifyError("Bad type");
}
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case SALOAD :
type = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_short_array()) {
verifyError("Bad type");
}
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case LALOAD :
type = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_long_array()) {
verifyError("Bad type");
}
current_frame.push_stack_2(
VerificationType.long_type,
VerificationType.long2_type);
no_control_flow = false; break;
case FALOAD :
type = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_float_array()) {
verifyError("Bad type");
}
current_frame.push_stack(
VerificationType.float_type);
no_control_flow = false; break;
case DALOAD :
type = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_double_array()) {
verifyError("Bad type");
}
current_frame.push_stack_2(
VerificationType.double_type,
VerificationType.double2_type);
no_control_flow = false; break;
case AALOAD : {
type = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_reference_array()) {
verifyError("Bad type");
}
if (atype.is_null()) {
current_frame.push_stack(
VerificationType.null_type);
} else {
VerificationType component =
atype.get_component(this);
current_frame.push_stack(component);
}
no_control_flow = false; break;
}
case ISTORE :
verify_istore(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case ISTORE_0 :
case ISTORE_1 :
case ISTORE_2 :
case ISTORE_3 :
index = opcode - ISTORE_0;
verify_istore(index, current_frame);
no_control_flow = false; break;
case LSTORE :
verify_lstore(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case LSTORE_0 :
case LSTORE_1 :
case LSTORE_2 :
case LSTORE_3 :
index = opcode - LSTORE_0;
verify_lstore(index, current_frame);
no_control_flow = false; break;
case FSTORE :
verify_fstore(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case FSTORE_0 :
case FSTORE_1 :
case FSTORE_2 :
case FSTORE_3 :
index = opcode - FSTORE_0;
verify_fstore(index, current_frame);
no_control_flow = false; break;
case DSTORE :
verify_dstore(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case DSTORE_0 :
case DSTORE_1 :
case DSTORE_2 :
case DSTORE_3 :
index = opcode - DSTORE_0;
verify_dstore(index, current_frame);
no_control_flow = false; break;
case ASTORE :
verify_astore(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case ASTORE_0 :
case ASTORE_1 :
case ASTORE_2 :
case ASTORE_3 :
index = opcode - ASTORE_0;
verify_astore(index, current_frame);
no_control_flow = false; break;
case IASTORE :
type = current_frame.pop_stack(
VerificationType.integer_type);
type2 = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_int_array()) {
verifyError("Bad type");
}
no_control_flow = false; break;
case BASTORE :
type = current_frame.pop_stack(
VerificationType.integer_type);
type2 = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_bool_array() && !atype.is_byte_array()) {
verifyError("Bad type");
}
no_control_flow = false; break;
case CASTORE :
current_frame.pop_stack(
VerificationType.integer_type);
current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_char_array()) {
verifyError("Bad type");
}
no_control_flow = false; break;
case SASTORE :
current_frame.pop_stack(
VerificationType.integer_type);
current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_short_array()) {
verifyError("Bad type");
}
no_control_flow = false; break;
case LASTORE :
current_frame.pop_stack_2(
VerificationType.long2_type,
VerificationType.long_type);
current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_long_array()) {
verifyError("Bad type");
}
no_control_flow = false; break;
case FASTORE :
current_frame.pop_stack(
VerificationType.float_type);
current_frame.pop_stack
(VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_float_array()) {
verifyError("Bad type");
}
no_control_flow = false; break;
case DASTORE :
current_frame.pop_stack_2(
VerificationType.double2_type,
VerificationType.double_type);
current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
if (!atype.is_double_array()) {
verifyError("Bad type");
}
no_control_flow = false; break;
case AASTORE :
type = current_frame.pop_stack(object_type());
type2 = current_frame.pop_stack(
VerificationType.integer_type);
atype = current_frame.pop_stack(
VerificationType.reference_check);
// more type-checking is done at runtime
if (!atype.is_reference_array()) {
verifyError("Bad type");
}
// 4938384: relaxed constraint in JVMS 3nd edition.
no_control_flow = false; break;
case POP :
current_frame.pop_stack(
VerificationType.category1_check);
no_control_flow = false; break;
case POP2 :
type = current_frame.pop_stack();
if (type.is_category1(this)) {
current_frame.pop_stack(
VerificationType.category1_check);
} else if (type.is_category2_2nd()) {
current_frame.pop_stack(
VerificationType.category2_check);
} else {
verifyError("Bad type");
}
no_control_flow = false; break;
case DUP :
type = current_frame.pop_stack(
VerificationType.category1_check);
current_frame.push_stack(type);
current_frame.push_stack(type);
no_control_flow = false; break;
case DUP_X1 :
type = current_frame.pop_stack(
VerificationType.category1_check);
type2 = current_frame.pop_stack(
VerificationType.category1_check);
current_frame.push_stack(type);
current_frame.push_stack(type2);
current_frame.push_stack(type);
no_control_flow = false; break;
case DUP_X2 :
{
VerificationType type3 = null;
type = current_frame.pop_stack(
VerificationType.category1_check);
type2 = current_frame.pop_stack();
if (type2.is_category1(this)) {
type3 = current_frame.pop_stack(
VerificationType.category1_check);
} else if (type2.is_category2_2nd()) {
type3 = current_frame.pop_stack(
VerificationType.category2_check);
} else {
verifyError("Bad type");
}
current_frame.push_stack(type);
current_frame.push_stack(type3);
current_frame.push_stack(type2);
current_frame.push_stack(type);
no_control_flow = false; break;
}
case DUP2 :
type = current_frame.pop_stack();
if (type.is_category1(this)) {
type2 = current_frame.pop_stack(
VerificationType.category1_check);
} else if (type.is_category2_2nd()) {
type2 = current_frame.pop_stack(
VerificationType.category2_check);
} else {
verifyError("Bad type");
}
current_frame.push_stack(type2);
current_frame.push_stack(type);
current_frame.push_stack(type2);
current_frame.push_stack(type);
no_control_flow = false; break;
case DUP2_X1 :
{
VerificationType type3;
type = current_frame.pop_stack();
if (type.is_category1(this)) {
type2 = current_frame.pop_stack(
VerificationType.category1_check);
} else if (type.is_category2_2nd()) {
type2 = current_frame.pop_stack(
VerificationType.category2_check);
} else {
verifyError("Bad type");
}
type3 = current_frame.pop_stack(
VerificationType.category1_check);
current_frame.push_stack(type2);
current_frame.push_stack(type);
current_frame.push_stack(type3);
current_frame.push_stack(type2);
current_frame.push_stack(type);
no_control_flow = false; break;
}
case DUP2_X2 :
VerificationType type3, type4 = null;
type = current_frame.pop_stack();
if (type.is_category1(this)) {
type2 = current_frame.pop_stack(
VerificationType.category1_check);
} else if (type.is_category2_2nd()) {
type2 = current_frame.pop_stack(
VerificationType.category2_check);
} else {
verifyError("Bad type");
}
type3 = current_frame.pop_stack();
if (type3.is_category1(this)) {
type4 = current_frame.pop_stack(
VerificationType.category1_check);
} else if (type3.is_category2_2nd()) {
type4 = current_frame.pop_stack(
VerificationType.category2_check);
} else {
verifyError("Bad type");
}
current_frame.push_stack(type2);
current_frame.push_stack(type);
current_frame.push_stack(type4);
current_frame.push_stack(type3);
current_frame.push_stack(type2);
current_frame.push_stack(type);
no_control_flow = false; break;
case SWAP :
type = current_frame.pop_stack(
VerificationType.category1_check);
type2 = current_frame.pop_stack(
VerificationType.category1_check);
current_frame.push_stack(type);
current_frame.push_stack(type2);
no_control_flow = false; break;
case IADD :
case ISUB :
case IMUL :
case IDIV :
case IREM :
case ISHL :
case ISHR :
case IUSHR :
case IOR :
case IXOR :
case IAND :
current_frame.pop_stack(
VerificationType.integer_type);
// fall through
case INEG :
current_frame.pop_stack(
VerificationType.integer_type);
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case LADD :
case LSUB :
case LMUL :
case LDIV :
case LREM :
case LAND :
case LOR :
case LXOR :
current_frame.pop_stack_2(
VerificationType.long2_type,
VerificationType.long_type);
// fall through
case LNEG :
current_frame.pop_stack_2(
VerificationType.long2_type,
VerificationType.long_type);
current_frame.push_stack_2(
VerificationType.long_type,
VerificationType.long2_type);
no_control_flow = false; break;
case LSHL :
case LSHR :
case LUSHR :
current_frame.pop_stack(
VerificationType.integer_type);
current_frame.pop_stack_2(
VerificationType.long2_type,
VerificationType.long_type);
current_frame.push_stack_2(
VerificationType.long_type,
VerificationType.long2_type);
no_control_flow = false; break;
case FADD :
case FSUB :
case FMUL :
case FDIV :
case FREM :
current_frame.pop_stack(
VerificationType.float_type);
// fall through
case FNEG :
current_frame.pop_stack(
VerificationType.float_type);
current_frame.push_stack(
VerificationType.float_type);
no_control_flow = false; break;
case DADD :
case DSUB :
case DMUL :
case DDIV :
case DREM :
current_frame.pop_stack_2(
VerificationType.double2_type,
VerificationType.double_type);
// fall through
case DNEG :
current_frame.pop_stack_2(
VerificationType.double2_type,
VerificationType.double_type);
current_frame.push_stack_2(
VerificationType.double_type,
VerificationType.double2_type);
no_control_flow = false; break;
case IINC :
verify_iinc(bcs.getIndex(), current_frame);
no_control_flow = false; break;
case I2L :
type = current_frame.pop_stack(
VerificationType.integer_type);
current_frame.push_stack_2(
VerificationType.long_type,
VerificationType.long2_type);
no_control_flow = false; break;
case L2I :
current_frame.pop_stack_2(
VerificationType.long2_type,
VerificationType.long_type);
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case I2F :
current_frame.pop_stack(
VerificationType.integer_type);
current_frame.push_stack(
VerificationType.float_type);
no_control_flow = false; break;
case I2D :
current_frame.pop_stack(
VerificationType.integer_type);
current_frame.push_stack_2(
VerificationType.double_type,
VerificationType.double2_type);
no_control_flow = false; break;
case L2F :
current_frame.pop_stack_2(
VerificationType.long2_type,
VerificationType.long_type);
current_frame.push_stack(
VerificationType.float_type);
no_control_flow = false; break;
case L2D :
current_frame.pop_stack_2(
VerificationType.long2_type,
VerificationType.long_type);
current_frame.push_stack_2(
VerificationType.double_type,
VerificationType.double2_type);
no_control_flow = false; break;
case F2I :
current_frame.pop_stack(
VerificationType.float_type);
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case F2L :
current_frame.pop_stack(
VerificationType.float_type);
current_frame.push_stack_2(
VerificationType.long_type,
VerificationType.long2_type);
no_control_flow = false; break;
case F2D :
current_frame.pop_stack(
VerificationType.float_type);
current_frame.push_stack_2(
VerificationType.double_type,
VerificationType.double2_type);
no_control_flow = false; break;
case D2I :
current_frame.pop_stack_2(
VerificationType.double2_type,
VerificationType.double_type);
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case D2L :
current_frame.pop_stack_2(
VerificationType.double2_type,
VerificationType.double_type);
current_frame.push_stack_2(
VerificationType.long_type,
VerificationType.long2_type);
no_control_flow = false; break;
case D2F :
current_frame.pop_stack_2(
VerificationType.double2_type,
VerificationType.double_type);
current_frame.push_stack(
VerificationType.float_type);
no_control_flow = false; break;
case I2B :
case I2C :
case I2S :
current_frame.pop_stack(
VerificationType.integer_type);
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case LCMP :
current_frame.pop_stack_2(
VerificationType.long2_type,
VerificationType.long_type);
current_frame.pop_stack_2(
VerificationType.long2_type,
VerificationType.long_type);
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case FCMPL :
case FCMPG :
current_frame.pop_stack(
VerificationType.float_type);
current_frame.pop_stack(
VerificationType.float_type);
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case DCMPL :
case DCMPG :
current_frame.pop_stack_2(
VerificationType.double2_type,
VerificationType.double_type);
current_frame.pop_stack_2(
VerificationType.double2_type,
VerificationType.double_type);
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case IF_ICMPEQ:
case IF_ICMPNE:
case IF_ICMPLT:
case IF_ICMPGE:
case IF_ICMPGT:
case IF_ICMPLE:
current_frame.pop_stack(
VerificationType.integer_type);
// fall through
case IFEQ:
case IFNE:
case IFLT:
case IFGE:
case IFGT:
case IFLE:
current_frame.pop_stack(
VerificationType.integer_type);
target = bcs.dest();
stackmap_table.check_jump_target(
current_frame, target);
no_control_flow = false; break;
case IF_ACMPEQ :
case IF_ACMPNE :
current_frame.pop_stack(
VerificationType.reference_check);
// fall through
case IFNULL :
case IFNONNULL :
current_frame.pop_stack(
VerificationType.reference_check);
target = bcs.dest();
stackmap_table.check_jump_target
(current_frame, target);
no_control_flow = false; break;
case GOTO :
target = bcs.dest();
stackmap_table.check_jump_target(
current_frame, target);
no_control_flow = true; break;
case GOTO_W :
target = bcs.destW();
stackmap_table.check_jump_target(
current_frame, target);
no_control_flow = true; break;
case TABLESWITCH :
case LOOKUPSWITCH :
verify_switch(
bcs, code_length, code_data, current_frame,
stackmap_table);
no_control_flow = true; break;
case IRETURN :
type = current_frame.pop_stack(
VerificationType.integer_type);
verify_return_value(return_type, type, bci,
current_frame);
no_control_flow = true; break;
case LRETURN :
type2 = current_frame.pop_stack(
VerificationType.long2_type);
type = current_frame.pop_stack(
VerificationType.long_type);
verify_return_value(return_type, type, bci,
current_frame);
no_control_flow = true; break;
case FRETURN :
type = current_frame.pop_stack(
VerificationType.float_type);
verify_return_value(return_type, type, bci,
current_frame);
no_control_flow = true; break;
case DRETURN :
type2 = current_frame.pop_stack(
VerificationType.double2_type);
type = current_frame.pop_stack(
VerificationType.double_type);
verify_return_value(return_type, type, bci,
current_frame);
no_control_flow = true; break;
case ARETURN :
type = current_frame.pop_stack(
VerificationType.reference_check);
verify_return_value(return_type, type, bci,
current_frame);
no_control_flow = true; break;
case RETURN:
if (!return_type.is_bogus()) {
verifyError("Method expects a return value");
}
if (object_initializer_name.equals(_method.name()) &&
current_frame.flag_this_uninit()) {
verifyError("Constructor must call super() or this() before return");
}
no_control_flow = true; break;
case GETSTATIC :
case PUTSTATIC :
verify_field_instructions(bcs, current_frame, cp, true);
no_control_flow = false; break;
case GETFIELD :
case PUTFIELD :
verify_field_instructions(bcs, current_frame, cp, false);
no_control_flow = false; break;
case INVOKEVIRTUAL :
case INVOKESPECIAL :
case INVOKESTATIC :
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);
no_control_flow = false; break;
case INVOKEINTERFACE :
case INVOKEDYNAMIC :
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);
no_control_flow = false; break;
case NEW :
{
index = bcs.getIndexU2();
verify_cp_class_type(bci, index, cp);
VerificationType new_class_type =
cp_index_to_type(index, cp);
if (!new_class_type.is_object()) {
verifyError("Illegal new instruction");
}
type = VerificationType.uninitialized_type(bci);
current_frame.push_stack(type);
no_control_flow = false; break;
}
case NEWARRAY :
type = get_newarray_type(bcs.getIndex(), bci);
current_frame.pop_stack(
VerificationType.integer_type);
current_frame.push_stack(type);
no_control_flow = false; break;
case ANEWARRAY :
verify_anewarray(bci, bcs.getIndexU2(), cp, current_frame);
no_control_flow = false; break;
case ARRAYLENGTH :
type = current_frame.pop_stack(
VerificationType.reference_check);
if (!(type.is_null() || type.is_array())) {
verifyError("Bad type");
}
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
case CHECKCAST :
{
index = bcs.getIndexU2();
verify_cp_class_type(bci, index, cp);
current_frame.pop_stack(object_type());
VerificationType klass_type = cp_index_to_type(
index, cp);
current_frame.push_stack(klass_type);
no_control_flow = false; break;
}
case INSTANCEOF : {
index = bcs.getIndexU2();
verify_cp_class_type(bci, index, cp);
current_frame.pop_stack(object_type());
current_frame.push_stack(
VerificationType.integer_type);
no_control_flow = false; break;
}
case MONITORENTER :
case MONITOREXIT :
current_frame.pop_stack(
VerificationType.reference_check);
no_control_flow = false; break;
case MULTIANEWARRAY :
{
index = bcs.getIndexU2();
int dim = _method.codeArray()[bcs.bci() +3] & 0xff;
verify_cp_class_type(bci, index, cp);
VerificationType new_array_type =
cp_index_to_type(index, cp);
if (!new_array_type.is_array()) {
verifyError("Illegal constant pool index in multianewarray instruction");
}
if (dim < 1 || new_array_type.dimensions(this) < dim) {
verifyError(String.format("Illegal dimension in multianewarray instruction: %d", dim));
}
for (int i = 0; i < dim; i++) {
current_frame.pop_stack(
VerificationType.integer_type);
}
current_frame.push_stack(new_array_type);
no_control_flow = false; break;
}
case ATHROW :
type = VerificationType.reference_type(java_lang_Throwable);
current_frame.pop_stack(type);
no_control_flow = true; break;
default:
verifyError(String.format("Bad instruction: %02x", opcode));
}
}
if (verified_exc_handlers && this_uninit) verifyError("Exception handler targets got verified before this_uninit got set");
if (!verified_exc_handlers && bci >= ex_minmax[0] && bci < ex_minmax[1]) {
verify_exception_handler_targets(bci, this_uninit, current_frame, stackmap_table);
}
}
if (!no_control_flow) {
verifyError("Control flow falls through code end");
}
}