src/share/vm/interpreter/linkResolver.cpp

changeset 8758
e7db67a9ddfd
parent 8716
619700f41f8e
parent 8739
0b85ccd62409
child 8841
cbb6bc4b8c86
child 8995
e413e0d0e467
     1.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Mon Mar 27 08:21:39 2017 -0700
     1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Mon Mar 27 11:31:27 2017 -0700
     1.3 @@ -915,11 +915,11 @@
     1.4  }
     1.5  
     1.6  
     1.7 -void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name,
     1.8 +void LinkResolver::resolve_special_call(CallInfo& result, Handle recv, KlassHandle resolved_klass, Symbol* method_name,
     1.9                                          Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
    1.10    methodHandle resolved_method;
    1.11    linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
    1.12 -  runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK);
    1.13 +  runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, recv, check_access, CHECK);
    1.14  }
    1.15  
    1.16  // throws linktime exceptions
    1.17 @@ -1018,7 +1018,7 @@
    1.18  
    1.19  // throws runtime exceptions
    1.20  void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
    1.21 -                                                  KlassHandle current_klass, bool check_access, TRAPS) {
    1.22 +                                                  KlassHandle current_klass, Handle recv, bool check_access, TRAPS) {
    1.23  
    1.24    // resolved method is selected method unless we have an old-style lookup
    1.25    // for a superclass method
    1.26 @@ -1026,21 +1026,19 @@
    1.27    // no checks for shadowing
    1.28    methodHandle sel_method(THREAD, resolved_method());
    1.29  
    1.30 +  if (check_access &&
    1.31 +      // check if the method is not <init>
    1.32 +      resolved_method->name() != vmSymbols::object_initializer_name()) {
    1.33 +
    1.34    // check if this is an old-style super call and do a new lookup if so
    1.35 -  { KlassHandle method_klass  = KlassHandle(THREAD,
    1.36 -                                            resolved_method->method_holder());
    1.37 -
    1.38 -    if (check_access &&
    1.39          // a) check if ACC_SUPER flag is set for the current class
    1.40 -        (current_klass->is_super() || !AllowNonVirtualCalls) &&
    1.41 +    if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
    1.42          // b) check if the class of the resolved_klass is a superclass
    1.43          // (not supertype in order to exclude interface classes) of the current class.
    1.44          // This check is not performed for super.invoke for interface methods
    1.45          // in super interfaces.
    1.46          current_klass->is_subclass_of(resolved_klass()) &&
    1.47 -        current_klass() != resolved_klass() &&
    1.48 -        // c) check if the method is not <init>
    1.49 -        resolved_method->name() != vmSymbols::object_initializer_name()) {
    1.50 +        current_klass() != resolved_klass()) {
    1.51        // Lookup super method
    1.52        KlassHandle super_klass(THREAD, current_klass->super());
    1.53        lookup_instance_method_in_klasses(sel_method, super_klass,
    1.54 @@ -1055,6 +1053,27 @@
    1.55                                              resolved_method->signature()));
    1.56        }
    1.57      }
    1.58 +
    1.59 +    // Check that the class of objectref (the receiver) is the current class or interface,
    1.60 +    // or a subtype of the current class or interface (the sender), otherwise invokespecial
    1.61 +    // throws IllegalAccessError.
    1.62 +    // The verifier checks that the sender is a subtype of the class in the I/MR operand.
    1.63 +    // The verifier also checks that the receiver is a subtype of the sender, if the sender is
    1.64 +    // a class.  If the sender is an interface, the check has to be performed at runtime.
    1.65 +    InstanceKlass* sender = InstanceKlass::cast(current_klass());
    1.66 +    sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender;
    1.67 +    if (sender->is_interface() && recv.not_null()) {
    1.68 +      Klass* receiver_klass = recv->klass();
    1.69 +      if (!receiver_klass->is_subtype_of(sender)) {
    1.70 +        ResourceMark rm(THREAD);
    1.71 +        char buf[500];
    1.72 +        jio_snprintf(buf, sizeof(buf),
    1.73 +                     "Receiver class %s must be the current class or a subtype of interface %s",
    1.74 +                     receiver_klass->name()->as_C_string(),
    1.75 +                     sender->name()->as_C_string());
    1.76 +        THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), buf);
    1.77 +      }
    1.78 +    }
    1.79    }
    1.80  
    1.81    // check if not static
    1.82 @@ -1481,7 +1500,7 @@
    1.83                                                    bool check_access) {
    1.84    EXCEPTION_MARK;
    1.85    CallInfo info;
    1.86 -  resolve_special_call(info, resolved_klass, name, signature, current_klass, check_access, THREAD);
    1.87 +  resolve_special_call(info, Handle(), resolved_klass, name, signature, current_klass, check_access, THREAD);
    1.88    if (HAS_PENDING_EXCEPTION) {
    1.89      CLEAR_PENDING_EXCEPTION;
    1.90      return methodHandle();
    1.91 @@ -1497,7 +1516,7 @@
    1.92  void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
    1.93    switch (byte) {
    1.94      case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
    1.95 -    case Bytecodes::_invokespecial  : resolve_invokespecial  (result,       pool, index, CHECK); break;
    1.96 +    case Bytecodes::_invokespecial  : resolve_invokespecial  (result, recv, pool, index, CHECK); break;
    1.97      case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
    1.98      case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
    1.99      case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
   1.100 @@ -1528,13 +1547,13 @@
   1.101  }
   1.102  
   1.103  
   1.104 -void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
   1.105 +void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
   1.106    KlassHandle  resolved_klass;
   1.107    Symbol* method_name = NULL;
   1.108    Symbol* method_signature = NULL;
   1.109    KlassHandle  current_klass;
   1.110    resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
   1.111 -  resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   1.112 +  resolve_special_call(result, recv, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   1.113  }
   1.114  
   1.115  

mercurial