8026022: Verifier: allow anon classes to invokespecial host class/intf methods.

Tue, 08 Oct 2013 16:58:23 -0400

author
acorn
date
Tue, 08 Oct 2013 16:58:23 -0400
changeset 5852
c72075c2883e
parent 5851
ced68a57cdbd
child 5853
d25557d03ec0

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));

mercurial