--- old/src/share/vm/classfile/verifier.cpp 2017-09-07 12:10:42.150518501 -0400 +++ new/src/share/vm/classfile/verifier.cpp 2017-09-07 12:10:40.862205299 -0400 @@ -239,8 +239,9 @@ return (should_verify_for(klass->class_loader(), should_verify_class) && // return if the class is a bootstrapping class // or defineClass specified not to verify by default (flags override passed arg) - // We need to skip the following four for bootstraping + // We need to skip the following few for bootstrapping name != vmSymbols::java_lang_Object() && + name != vmSymbols::java_lang____Value() && name != vmSymbols::java_lang_Class() && name != vmSymbols::java_lang_String() && name != vmSymbols::java_lang_Throwable() && @@ -251,6 +252,11 @@ // Shared classes shouldn't have stackmaps either. !klass->is_shared() && + // A MVT derived value type contains no code atrribute - no private static + // methods, no instance methods, no , no . So while format + // checking is performed on it, verification is not. + (!((EnableMVT || EnableValhalla) && klass->access_flags().is_value_type())) && + // As of the fix for 4486457 we disable verification for all of the // dynamically-generated bytecodes associated with the 1.4 // reflection implementation, not just those associated with @@ -584,12 +590,22 @@ return VerificationType::reference_type(vmSymbols::java_lang_Object()); } +VerificationType ClassVerifier::__value_type() const { + return VerificationType::valuetype_type(vmSymbols::java_lang____Value()); +} + TypeOrigin ClassVerifier::ref_ctx(const char* sig, TRAPS) { VerificationType vt = VerificationType::reference_type( create_temporary_symbol(sig, (int)strlen(sig), THREAD)); return TypeOrigin::implicit(vt); } +TypeOrigin ClassVerifier::valuetype_ctx(const char* sig, TRAPS) { + VerificationType vt = VerificationType::valuetype_type( + create_temporary_symbol(sig, (int)strlen(sig), THREAD)); + return TypeOrigin::implicit(vt); +} + void ClassVerifier::verify_class(TRAPS) { log_info(verification)("Verifying class %s with new format", _klass->external_name()); @@ -634,6 +650,12 @@ return; } + // Verify value type bytecodes if enabled and class file version supports them. + // Commented check out for now until class file version 54.1 is generated. + bool vbytecodes_allowed = (EnableMVT || EnableValhalla); + //_klass->major_version() >= Verifier::VALUETYPE_MAJOR_VERSION && + //_klass->minor_version() >= Verifier::VALUETYPE_MINOR_VERSION); + // Initial stack map frame: offset is 0, stack is initially empty. StackMapFrame current_frame(max_locals, max_stack, this); // Set initial locals @@ -841,6 +863,15 @@ index = opcode - Bytecodes::_dload_0; verify_dload(index, ¤t_frame, CHECK_VERIFY(this)); no_control_flow = false; break; + case Bytecodes::_vload : + if (!vbytecodes_allowed) { + class_format_error( + "vload not supported by this class file version (%d.%d), class %s", + _klass->major_version(), _klass->minor_version(), _klass->external_name()); + return; + } + verify_vload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); + no_control_flow = false; break; case Bytecodes::_aload : verify_aload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); no_control_flow = false; break; @@ -973,6 +1004,37 @@ } no_control_flow = false; break; } + case Bytecodes::_vaload : { + if (!vbytecodes_allowed) { + class_format_error( + "vaload not supported by this class file version (%d.%d), class %s", + _klass->major_version(), _klass->minor_version(), _klass->external_name()); + return; + } + type = current_frame.pop_stack( + VerificationType::integer_type(), CHECK_VERIFY(this)); + atype = current_frame.pop_stack( + VerificationType::reference_check(), CHECK_VERIFY(this)); + // The null check is strictly not be necessary, left in for future proofing. + // Will be reconsidered if type indexes are removed. + if (atype.is_null() || !atype.is_value_array()) { + verify_error(ErrorContext::bad_type(bci, + current_frame.stack_top_ctx(), + TypeOrigin::implicit(VerificationType::reference_check())), + bad_type_msg, "vaload"); + return; + } + VerificationType component = atype.get_component(this, CHECK_VERIFY(this)); + if (!component.is_valuetype()) { + verify_error(ErrorContext::bad_type(bci, + current_frame.stack_top_ctx(), + TypeOrigin::implicit(VerificationType::valuetype_check())), + bad_type_msg, "vaload"); + return; + } + current_frame.push_stack(component, CHECK_VERIFY(this)); + no_control_flow = false; break; + } case Bytecodes::_istore : verify_istore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); no_control_flow = false; break; @@ -1013,6 +1075,15 @@ index = opcode - Bytecodes::_dstore_0; verify_dstore(index, ¤t_frame, CHECK_VERIFY(this)); no_control_flow = false; break; + case Bytecodes::_vstore : + if (!vbytecodes_allowed) { + class_format_error( + "vstore not supported by this class file version (%d.%d), class %s", + _klass->major_version(), _klass->minor_version(), _klass->external_name()); + return; + } + verify_vstore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); + no_control_flow = false; break; case Bytecodes::_astore : verify_astore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this)); no_control_flow = false; break; @@ -1139,6 +1210,28 @@ } // 4938384: relaxed constraint in JVMS 3nd edition. no_control_flow = false; break; + case Bytecodes::_vastore : + if (!vbytecodes_allowed) { + class_format_error( + "vastore not supported by this class file version (%d.%d), class %s", + _klass->major_version(), _klass->minor_version(), _klass->external_name()); + return; + } + type = current_frame.pop_stack(__value_type(), CHECK_VERIFY(this)); + type2 = current_frame.pop_stack( + VerificationType::integer_type(), CHECK_VERIFY(this)); + atype = current_frame.pop_stack( + VerificationType::reference_check(), CHECK_VERIFY(this)); + // The null check is strictly not be necessary, left in for future proofing. + // Will be reconsidered if type indexes are removed. + if (atype.is_null() || !atype.is_value_array()) { + verify_error(ErrorContext::bad_type(bci, + current_frame.stack_top_ctx(), + TypeOrigin::implicit(VerificationType::reference_check())), + bad_type_msg, "vastore"); + return; + } + no_control_flow = false; break; case Bytecodes::_pop : current_frame.pop_stack( VerificationType::category1_check(), CHECK_VERIFY(this)); @@ -1590,6 +1683,18 @@ verify_return_value(return_type, type, bci, ¤t_frame, CHECK_VERIFY(this)); no_control_flow = true; break; + case Bytecodes::_vreturn : + if (!vbytecodes_allowed) { + class_format_error( + "vreturn not supported by this class file version (%d.%d), class %s", + _klass->major_version(), _klass->minor_version(), _klass->external_name()); + return; + } + type = current_frame.pop_stack( + VerificationType::valuetype_check(), CHECK_VERIFY(this)); + verify_return_value(return_type, type, bci, + ¤t_frame, CHECK_VERIFY(this)); + no_control_flow = true; break; case Bytecodes::_return : if (return_type != VerificationType::bogus_type()) { verify_error(ErrorContext::bad_code(bci), @@ -1618,6 +1723,15 @@ verify_field_instructions( &bcs, ¤t_frame, cp, false, CHECK_VERIFY(this)); no_control_flow = false; break; + case Bytecodes::_vwithfield : + if (!vbytecodes_allowed) { + class_format_error( + "vwithfield not supported by this class file version (%d.%d), class %s", + _klass->major_version(), _klass->minor_version(), _klass->external_name()); + return; + } + verify_vwithfield(&bcs, ¤t_frame, cp, CHECK_VERIFY(this)); + no_control_flow = false; break; case Bytecodes::_invokevirtual : case Bytecodes::_invokespecial : case Bytecodes::_invokestatic : @@ -1636,7 +1750,7 @@ index = bcs.get_index_u2(); verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this)); VerificationType new_class_type = - cp_index_to_type(index, cp, CHECK_VERIFY(this)); + cp_index_to_reference_type(index, cp, CHECK_VERIFY(this)); if (!new_class_type.is_object()) { verify_error(ErrorContext::bad_type(bci, TypeOrigin::cp(index, new_class_type)), @@ -1647,6 +1761,27 @@ current_frame.push_stack(type, CHECK_VERIFY(this)); no_control_flow = false; break; } + case Bytecodes::_vdefault : + { + if (!vbytecodes_allowed) { + class_format_error( + "vdefault not supported by this class file version (%d.%d), class %s", + _klass->major_version(), _klass->minor_version(), _klass->external_name()); + return; + } + index = bcs.get_index_u2(); + verify_cp_value_type(bci, index, cp, CHECK_VERIFY(this)); + VerificationType new_value_type = + cp_index_to_valuetype(index, cp, CHECK_VERIFY(this)); + if (!new_value_type.is_valuetype()) { + verify_error(ErrorContext::bad_type(bci, + TypeOrigin::cp(index, new_value_type)), + "Illegal vdefault instruction"); + return; + } + current_frame.push_stack(new_value_type, CHECK_VERIFY(this)); + no_control_flow = false; break; + } case Bytecodes::_newarray : type = get_newarray_type(bcs.get_index(), bci, CHECK_VERIFY(this)); current_frame.pop_stack( @@ -1673,7 +1808,7 @@ index = bcs.get_index_u2(); verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this)); current_frame.pop_stack(object_type(), CHECK_VERIFY(this)); - VerificationType klass_type = cp_index_to_type( + VerificationType klass_type = cp_index_to_reference_type( index, cp, CHECK_VERIFY(this)); current_frame.push_stack(klass_type, CHECK_VERIFY(this)); no_control_flow = false; break; @@ -1686,6 +1821,36 @@ VerificationType::integer_type(), CHECK_VERIFY(this)); no_control_flow = false; break; } + case Bytecodes::_vbox : { + if (!EnableMVT || !vbytecodes_allowed) { + class_format_error( + "vbox not supported by this class file version (%d.%d), class %s", + _klass->major_version(), _klass->minor_version(), _klass->external_name()); + return; + } + index = bcs.get_index_u2(); + verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this)); + current_frame.pop_stack(VerificationType::valuetype_check(), CHECK_VERIFY(this)); + VerificationType klass_type = cp_index_to_reference_type( + index, cp, CHECK_VERIFY(this)); + current_frame.push_stack(klass_type, CHECK_VERIFY(this)); + no_control_flow = false; break; + } + case Bytecodes::_vunbox : { + if (!EnableMVT || !vbytecodes_allowed) { + class_format_error( + "vunbox not supported by this class file version (%d.%d), class %s", + _klass->major_version(), _klass->minor_version(), _klass->external_name()); + return; + } + index = bcs.get_index_u2(); + verify_cp_value_type(bci, index, cp, CHECK_VERIFY(this)); + current_frame.pop_stack(object_type(), CHECK_VERIFY(this)); + VerificationType value_type = cp_index_to_valuetype( + index, cp, CHECK_VERIFY(this)); + current_frame.push_stack(value_type, CHECK_VERIFY(this)); + no_control_flow = false; break; + } case Bytecodes::_monitorenter : case Bytecodes::_monitorexit : current_frame.pop_stack( @@ -1695,9 +1860,9 @@ { index = bcs.get_index_u2(); u2 dim = *(bcs.bcp()+3); - verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this)); + verify_cp_class_or_value_type(bci, index, cp, CHECK_VERIFY(this)); VerificationType new_array_type = - cp_index_to_type(index, cp, CHECK_VERIFY(this)); + cp_index_to_reference_type(index, cp, CHECK_VERIFY(this)); if (!new_array_type.is_array()) { verify_error(ErrorContext::bad_type(bci, TypeOrigin::cp(index, new_array_type)), @@ -1804,7 +1969,7 @@ } int catch_type_index = exhandlers.catch_type_index(i); if (catch_type_index != 0) { - VerificationType catch_type = cp_index_to_type( + VerificationType catch_type = cp_index_to_reference_type( catch_type_index, cp, CHECK_VERIFY(this)); VerificationType throwable = VerificationType::reference_type(vmSymbols::java_lang_Throwable()); @@ -1907,7 +2072,7 @@ if (catch_type_index != 0) { if (was_recursively_verified()) return; // We know that this index refers to a subclass of Throwable - VerificationType catch_type = cp_index_to_type( + VerificationType catch_type = cp_index_to_reference_type( catch_type_index, cp, CHECK_VERIFY(this)); new_frame->push_stack(catch_type, CHECK_VERIFY(this)); } else { @@ -1949,6 +2114,11 @@ verify_cp_index(bci, cp, index, CHECK_VERIFY(this)); unsigned int tag = cp->tag_at(index).value(); + + if (tag == JVM_CONSTANT_Value) { + tag = SAFE_JVM_CONSTANT_Value; //avoid overflow + } + if ((types & (1 << tag)) == 0) { verify_error(ErrorContext::bad_cp_index(bci, index), "Illegal type at constant pool entry %d in class %s", @@ -1969,6 +2139,32 @@ } } +void ClassVerifier::verify_cp_value_type( + u2 bci, int index, const constantPoolHandle& cp, TRAPS) { + verify_cp_index(bci, cp, index, CHECK_VERIFY(this)); + constantTag tag = cp->tag_at(index); + if (!tag.is_value_type() && !tag.is_unresolved_value_type()) { + verify_error(ErrorContext::bad_cp_index(bci, index), + "Illegal type at constant pool entry %d in class %s", + index, cp->pool_holder()->external_name()); + return; + } +} + +// Used for MVT value type overloaded bytecodes (anewarray, getfield, multianewarray) +void ClassVerifier::verify_cp_class_or_value_type( + u2 bci, int index, const constantPoolHandle& cp, TRAPS) { + verify_cp_index(bci, cp, index, CHECK_VERIFY(this)); + constantTag tag = cp->tag_at(index); + if (!tag.is_klass() && !tag.is_unresolved_klass() && + !tag.is_value_type() && !tag.is_unresolved_value_type()) { + verify_error(ErrorContext::bad_cp_index(bci, index), + "Illegal type at constant pool entry %d in class %s", + index, cp->pool_holder()->external_name()); + return; + } +} + void ClassVerifier::verify_error(ErrorContext ctx, const char* msg, ...) { stringStream ss; @@ -2056,12 +2252,17 @@ constantTag tag = cp->tag_at(index); unsigned int types; if (opcode == Bytecodes::_ldc || opcode == Bytecodes::_ldc_w) { - if (!tag.is_unresolved_klass()) { + if (!tag.is_unresolved_klass() && !tag.is_unresolved_value_type()) { types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float) - | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class) + | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class) + | (1 << SAFE_JVM_CONSTANT_Value) | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType); // Note: The class file parser already verified the legality of // MethodHandle and MethodType constants. + // Note: SAFE_JVM_CONSTANT_Value is used instead of JVM_CONSTANT_Value + // since JVM_CONSTANT_Value is an internally defined CP tag that is + // defined with a large value. When shifting left JVM_CONSTANT_Value + // would overrun the width of types. verify_cp_type(bci, index, cp, types, CHECK_VERIFY(this)); } } else { @@ -2075,7 +2276,8 @@ current_frame->push_stack( VerificationType::reference_type( vmSymbols::java_lang_String()), CHECK_VERIFY(this)); - } else if (tag.is_klass() || tag.is_unresolved_klass()) { + } else if (tag.is_klass() || tag.is_unresolved_klass() || + tag.is_value_type() || tag.is_unresolved_value_type()) { current_frame->push_stack( VerificationType::reference_type( vmSymbols::java_lang_Class()), CHECK_VERIFY(this)); @@ -2211,17 +2413,34 @@ return; } - // Get referenced class type - VerificationType ref_class_type = cp_ref_index_to_type( - index, cp, CHECK_VERIFY(this)); - if (!ref_class_type.is_object() && - (!allow_arrays || !ref_class_type.is_array())) { - verify_error(ErrorContext::bad_type(bcs->bci(), - TypeOrigin::cp(index, ref_class_type)), - "Expecting reference to class in class %s at constant pool index %d", - _klass->external_name(), index); - return; + // Get referenced class or value type + constantTag field_class_tag = cp->tag_at(cp->klass_ref_index_at(index)); + VerificationType ref_class_type; + + // getfield is overloaded to allow for either a reference or value type + if (bcs->raw_code() == Bytecodes::_getfield && + (EnableMVT || EnableValhalla) && + (field_class_tag.is_value_type() || field_class_tag.is_unresolved_value_type())) { + ref_class_type = cp_value_index_to_type(index, cp, CHECK_VERIFY(this)); + if (!ref_class_type.is_valuetype()) { + verify_error(ErrorContext::bad_type(bcs->bci(), + TypeOrigin::cp(index, ref_class_type)), + "Expecting reference to value type in class %s at constant pool index %d", + _klass->external_name(), index); + return; + } + } else { + ref_class_type = cp_ref_index_to_type(index, cp, CHECK_VERIFY(this)); + if (!ref_class_type.is_object() && + (!allow_arrays || !ref_class_type.is_array())) { + verify_error(ErrorContext::bad_type(bcs->bci(), + TypeOrigin::cp(index, ref_class_type)), + "Expecting reference to class in class %s at constant pool index %d", + _klass->external_name(), index); + return; + } } + VerificationType target_class_type = ref_class_type; assert(sizeof(VerificationType) == sizeof(uintptr_t), @@ -2318,6 +2537,74 @@ } } +void ClassVerifier::verify_vwithfield(RawBytecodeStream* bcs, + StackMapFrame* current_frame, + const constantPoolHandle& cp, + TRAPS) { + u2 index = bcs->get_index_u2(); + verify_cp_type(bcs->bci(), index, cp, + 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this)); + + // Get field name and signature + Symbol* field_name = cp->name_ref_at(index); + Symbol* field_sig = cp->signature_ref_at(index); + + if (!SignatureVerifier::is_valid_type_signature(field_sig)) { + class_format_error( + "Invalid signature for field in value type %s referenced " + "from constant pool index %d", _klass->external_name(), index); + return; + } + + // Check referenced value type + VerificationType ref_value_type = cp_value_index_to_type( + index, cp, CHECK_VERIFY(this)); + if (!ref_value_type.is_valuetype()) { + verify_error(ErrorContext::bad_type(bcs->bci(), + TypeOrigin::cp(index, ref_value_type)), + "Expecting reference to value type in class %s at constant pool index %d", + _klass->external_name(), index); + return; + } + VerificationType target_value_type = ref_value_type; + + assert(sizeof(VerificationType) == sizeof(uintptr_t), + "buffer type must match VerificationType size"); + uintptr_t field_type_buffer[2]; + VerificationType* field_type = (VerificationType*)field_type_buffer; + // If we make a VerificationType[2] array directly, the compiler calls + // to the c-runtime library to do the allocation instead of just + // stack allocating it. Plus it would run constructors. This shows up + // in performance profiles. + + SignatureStream sig_stream(field_sig, false); + int n = change_sig_to_verificationType( + &sig_stream, field_type, CHECK_VERIFY(this)); + u2 bci = bcs->bci(); + + // The type of value2 must be compatible with the descriptor of the referenced field. + // n could be 2 if it is a double or long. + for (int i = n - 1; i >= 0; i--) { + current_frame->pop_stack(field_type[i], CHECK_VERIFY(this)); + } + + // The type of value1 must be the direct value class type appearing in the field reference. + VerificationType stack_object_type = current_frame->pop_stack(CHECK_VERIFY(this)); + + bool is_assignable = target_value_type.is_assignable_from( + stack_object_type, this, false, CHECK_VERIFY(this)); + if (!is_assignable) { + verify_error(ErrorContext::bad_type(bci, + current_frame->stack_top_ctx(), + TypeOrigin::cp(index, target_value_type)), + "Bad type on operand stack in vwithfield"); + return; + } + + // The derived value class instance from another, modifying a field + current_frame->push_stack(stack_object_type, CHECK_VERIFY(this)); +} + // Look at the method's handlers. If the bci is in the handler's try block // then check if the handler_pc is already on the stack. If not, push it // unless the handler has already been scanned. @@ -2587,7 +2874,7 @@ verify_cp_class_type(bci, new_class_index, cp, CHECK_VERIFY(this)); // The method must be an method of the indicated class - VerificationType new_class_type = cp_index_to_type( + VerificationType new_class_type = cp_index_to_reference_type( new_class_index, cp, CHECK_VERIFY(this)); if (!new_class_type.equals(ref_class_type)) { verify_error(ErrorContext::bad_type(bci, @@ -2695,7 +2982,7 @@ return; } - // Get referenced class type + // Get referenced class or value type VerificationType ref_class_type; if (opcode == Bytecodes::_invokedynamic) { if (_klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) { @@ -2705,7 +2992,14 @@ return; } } else { - ref_class_type = cp_ref_index_to_type(index, cp, CHECK_VERIFY(this)); + constantTag method_class_tag = cp->tag_at(cp->klass_ref_index_at(index)); + if (EnableValhalla && + opcode == Bytecodes::_invokevirtual && + (method_class_tag.is_value_type() || method_class_tag.is_unresolved_value_type())) { + ref_class_type = cp_value_index_to_type(index, cp, CHECK_VERIFY(this)); + } else { + ref_class_type = cp_ref_index_to_type(index, cp, CHECK_VERIFY(this)); + } } // For a small signature length, we just allocate 128 bytes instead @@ -2930,13 +3224,18 @@ void ClassVerifier::verify_anewarray( u2 bci, u2 index, const constantPoolHandle& cp, StackMapFrame* current_frame, TRAPS) { - verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this)); + verify_cp_class_or_value_type(bci, index, cp, CHECK_VERIFY(this)); current_frame->pop_stack( VerificationType::integer_type(), CHECK_VERIFY(this)); if (was_recursively_verified()) return; - VerificationType component_type = - cp_index_to_type(index, cp, CHECK_VERIFY(this)); + constantTag class_tag = cp->tag_at(index); + VerificationType component_type; + if (class_tag.is_value_type() || class_tag.is_unresolved_value_type()) { + component_type = cp_index_to_valuetype(index, cp, CHECK_VERIFY(this)); + } else { + component_type = cp_index_to_reference_type(index, cp, CHECK_VERIFY(this)); + } int length; char* arr_sig_str; if (component_type.is_array()) { // it's an array @@ -2955,11 +3254,11 @@ strncpy(&arr_sig_str[1], component_name, length - 1); } else { // it's an object or interface const char* component_name = component_type.name()->as_utf8(); - // add one dimension to component with 'L' prepended and ';' postpended. + // add one dimension to component with 'L' or 'Q' (value type) prepended and ';' appended. length = (int)strlen(component_name) + 3; arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length); arr_sig_str[0] = '['; - arr_sig_str[1] = 'L'; + arr_sig_str[1] = component_type.is_reference() ? 'L' : 'Q'; strncpy(&arr_sig_str[2], component_name, length - 2); arr_sig_str[length - 1] = ';'; } @@ -3007,6 +3306,12 @@ current_frame->push_stack(type, CHECK_VERIFY(this)); } +void ClassVerifier::verify_vload(u2 index, StackMapFrame* current_frame, TRAPS) { + VerificationType type = current_frame->get_local( + index, VerificationType::valuetype_check(), CHECK_VERIFY(this)); + current_frame->push_stack(type, CHECK_VERIFY(this)); +} + void ClassVerifier::verify_istore(u2 index, StackMapFrame* current_frame, TRAPS) { current_frame->pop_stack( VerificationType::integer_type(), CHECK_VERIFY(this)); @@ -3044,6 +3349,12 @@ current_frame->set_local(index, type, CHECK_VERIFY(this)); } +void ClassVerifier::verify_vstore(u2 index, StackMapFrame* current_frame, TRAPS) { + VerificationType type = current_frame->pop_stack( + VerificationType::valuetype_check(), CHECK_VERIFY(this)); + current_frame->set_local(index, type, CHECK_VERIFY(this)); +} + void ClassVerifier::verify_iinc(u2 index, StackMapFrame* current_frame, TRAPS) { VerificationType type = current_frame->get_local( index, VerificationType::integer_type(), CHECK_VERIFY(this));