diff --git a/src/share/vm/classfile/verifier.cpp b/src/share/vm/classfile/verifier.cpp index 7134e7cdb268b2ddc11e04deb95f39892c97f30c..d645e27713695bc458249a4a7d959ccc416ba589 100644 --- a/src/share/vm/classfile/verifier.cpp +++ b/src/share/vm/classfile/verifier.cpp @@ -2442,10 +2442,16 @@ void ClassVerifier::verify_invoke_instructions( bool subtype = ref_class_type.is_assignable_from( current_type(), this, CHECK_VERIFY(this)); if (!subtype) { - verify_error(ErrorContext::bad_code(bci), - "Bad invokespecial instruction: " - "current class isn't assignable to reference class."); - return; + if (current_class()->is_anonymous()) { + subtype = ref_class_type.is_assignable_from(VerificationType::reference_type( + current_class()->host_klass()->name()), this, CHECK_VERIFY(this)); + } + if (!subtype) { + verify_error(ErrorContext::bad_code(bci), + "Bad invokespecial instruction: " + "current class isn't assignable to reference class."); + return; + } } } // Match method descriptor with operand stack @@ -2461,7 +2467,28 @@ void ClassVerifier::verify_invoke_instructions( } else { // other methods // Ensures that target class is assignable to method class. if (opcode == Bytecodes::_invokespecial) { - current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); + if (!current_class()->is_anonymous()) { + current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); + } else { + // anonymous class invokespecial calls: either the + // operand stack/objectref is a subtype of the current class OR + // the objectref is a subtype of the host_klass of the current class + // to allow an anonymous class to reference methods in the host_klass + VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this)); + bool subtype = current_type().is_assignable_from(top, this, CHECK_VERIFY(this)); + if (!subtype) { + VerificationType hosttype = + VerificationType::reference_type(current_class()->host_klass()->name()); + subtype = hosttype.is_assignable_from(top, this, CHECK_VERIFY(this)); + } + if (!subtype) { + verify_error( ErrorContext::bad_type(current_frame->offset(), + current_frame->stack_top_ctx(), + TypeOrigin::implicit(top)), + "Bad type on operand stack"); + return; + } + } } else if (opcode == Bytecodes::_invokevirtual) { VerificationType stack_object_type = current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this));