Tue, 08 Oct 2013 16:58:23 -0400
8026022: Verifier: allow anon classes to invokespecial host class/intf methods.
Reviewed-by: coleenp, bharadwaj
src/share/vm/classfile/verifier.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/share/vm/classfile/verifier.cpp Tue Oct 08 11:37:54 2013 +0200 1.2 +++ b/src/share/vm/classfile/verifier.cpp Tue Oct 08 16:58:23 2013 -0400 1.3 @@ -2442,10 +2442,16 @@ 1.4 bool subtype = ref_class_type.is_assignable_from( 1.5 current_type(), this, CHECK_VERIFY(this)); 1.6 if (!subtype) { 1.7 - verify_error(ErrorContext::bad_code(bci), 1.8 - "Bad invokespecial instruction: " 1.9 - "current class isn't assignable to reference class."); 1.10 - return; 1.11 + if (current_class()->is_anonymous()) { 1.12 + subtype = ref_class_type.is_assignable_from(VerificationType::reference_type( 1.13 + current_class()->host_klass()->name()), this, CHECK_VERIFY(this)); 1.14 + } 1.15 + if (!subtype) { 1.16 + verify_error(ErrorContext::bad_code(bci), 1.17 + "Bad invokespecial instruction: " 1.18 + "current class isn't assignable to reference class."); 1.19 + return; 1.20 + } 1.21 } 1.22 } 1.23 // Match method descriptor with operand stack 1.24 @@ -2461,7 +2467,28 @@ 1.25 } else { // other methods 1.26 // Ensures that target class is assignable to method class. 1.27 if (opcode == Bytecodes::_invokespecial) { 1.28 - current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); 1.29 + if (!current_class()->is_anonymous()) { 1.30 + current_frame->pop_stack(current_type(), CHECK_VERIFY(this)); 1.31 + } else { 1.32 + // anonymous class invokespecial calls: either the 1.33 + // operand stack/objectref is a subtype of the current class OR 1.34 + // the objectref is a subtype of the host_klass of the current class 1.35 + // to allow an anonymous class to reference methods in the host_klass 1.36 + VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this)); 1.37 + bool subtype = current_type().is_assignable_from(top, this, CHECK_VERIFY(this)); 1.38 + if (!subtype) { 1.39 + VerificationType hosttype = 1.40 + VerificationType::reference_type(current_class()->host_klass()->name()); 1.41 + subtype = hosttype.is_assignable_from(top, this, CHECK_VERIFY(this)); 1.42 + } 1.43 + if (!subtype) { 1.44 + verify_error( ErrorContext::bad_type(current_frame->offset(), 1.45 + current_frame->stack_top_ctx(), 1.46 + TypeOrigin::implicit(top)), 1.47 + "Bad type on operand stack"); 1.48 + return; 1.49 + } 1.50 + } 1.51 } else if (opcode == Bytecodes::_invokevirtual) { 1.52 VerificationType stack_object_type = 1.53 current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this));