src/share/vm/interpreter/linkResolver.cpp

changeset 8914
75000d7dd468
parent 8739
0b85ccd62409
child 8758
e7db67a9ddfd
child 8839
158904fa31b2
     1.1 --- a/src/share/vm/interpreter/linkResolver.cpp	Mon Nov 21 22:56:59 2016 -0800
     1.2 +++ b/src/share/vm/interpreter/linkResolver.cpp	Tue Dec 13 14:37:04 2016 -0500
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -913,11 +913,11 @@
    1.11  }
    1.12  
    1.13  
    1.14 -void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name,
    1.15 +void LinkResolver::resolve_special_call(CallInfo& result, Handle recv, KlassHandle resolved_klass, Symbol* method_name,
    1.16                                          Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
    1.17    methodHandle resolved_method;
    1.18    linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
    1.19 -  runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK);
    1.20 +  runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, recv, check_access, CHECK);
    1.21  }
    1.22  
    1.23  // throws linktime exceptions
    1.24 @@ -1016,7 +1016,7 @@
    1.25  
    1.26  // throws runtime exceptions
    1.27  void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
    1.28 -                                                  KlassHandle current_klass, bool check_access, TRAPS) {
    1.29 +                                                  KlassHandle current_klass, Handle recv, bool check_access, TRAPS) {
    1.30  
    1.31    // resolved method is selected method unless we have an old-style lookup
    1.32    // for a superclass method
    1.33 @@ -1024,21 +1024,19 @@
    1.34    // no checks for shadowing
    1.35    methodHandle sel_method(THREAD, resolved_method());
    1.36  
    1.37 +  if (check_access &&
    1.38 +      // check if the method is not <init>
    1.39 +      resolved_method->name() != vmSymbols::object_initializer_name()) {
    1.40 +
    1.41    // check if this is an old-style super call and do a new lookup if so
    1.42 -  { KlassHandle method_klass  = KlassHandle(THREAD,
    1.43 -                                            resolved_method->method_holder());
    1.44 -
    1.45 -    if (check_access &&
    1.46          // a) check if ACC_SUPER flag is set for the current class
    1.47 -        (current_klass->is_super() || !AllowNonVirtualCalls) &&
    1.48 +    if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
    1.49          // b) check if the class of the resolved_klass is a superclass
    1.50          // (not supertype in order to exclude interface classes) of the current class.
    1.51          // This check is not performed for super.invoke for interface methods
    1.52          // in super interfaces.
    1.53          current_klass->is_subclass_of(resolved_klass()) &&
    1.54 -        current_klass() != resolved_klass() &&
    1.55 -        // c) check if the method is not <init>
    1.56 -        resolved_method->name() != vmSymbols::object_initializer_name()) {
    1.57 +        current_klass() != resolved_klass()) {
    1.58        // Lookup super method
    1.59        KlassHandle super_klass(THREAD, current_klass->super());
    1.60        lookup_instance_method_in_klasses(sel_method, super_klass,
    1.61 @@ -1053,6 +1051,27 @@
    1.62                                              resolved_method->signature()));
    1.63        }
    1.64      }
    1.65 +
    1.66 +    // Check that the class of objectref (the receiver) is the current class or interface,
    1.67 +    // or a subtype of the current class or interface (the sender), otherwise invokespecial
    1.68 +    // throws IllegalAccessError.
    1.69 +    // The verifier checks that the sender is a subtype of the class in the I/MR operand.
    1.70 +    // The verifier also checks that the receiver is a subtype of the sender, if the sender is
    1.71 +    // a class.  If the sender is an interface, the check has to be performed at runtime.
    1.72 +    InstanceKlass* sender = InstanceKlass::cast(current_klass());
    1.73 +    sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender;
    1.74 +    if (sender->is_interface() && recv.not_null()) {
    1.75 +      Klass* receiver_klass = recv->klass();
    1.76 +      if (!receiver_klass->is_subtype_of(sender)) {
    1.77 +        ResourceMark rm(THREAD);
    1.78 +        char buf[500];
    1.79 +        jio_snprintf(buf, sizeof(buf),
    1.80 +                     "Receiver class %s must be the current class or a subtype of interface %s",
    1.81 +                     receiver_klass->name()->as_C_string(),
    1.82 +                     sender->name()->as_C_string());
    1.83 +        THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), buf);
    1.84 +      }
    1.85 +    }
    1.86    }
    1.87  
    1.88    // check if not static
    1.89 @@ -1479,7 +1498,7 @@
    1.90                                                    bool check_access) {
    1.91    EXCEPTION_MARK;
    1.92    CallInfo info;
    1.93 -  resolve_special_call(info, resolved_klass, name, signature, current_klass, check_access, THREAD);
    1.94 +  resolve_special_call(info, Handle(), resolved_klass, name, signature, current_klass, check_access, THREAD);
    1.95    if (HAS_PENDING_EXCEPTION) {
    1.96      CLEAR_PENDING_EXCEPTION;
    1.97      return methodHandle();
    1.98 @@ -1495,7 +1514,7 @@
    1.99  void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
   1.100    switch (byte) {
   1.101      case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
   1.102 -    case Bytecodes::_invokespecial  : resolve_invokespecial  (result,       pool, index, CHECK); break;
   1.103 +    case Bytecodes::_invokespecial  : resolve_invokespecial  (result, recv, pool, index, CHECK); break;
   1.104      case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
   1.105      case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
   1.106      case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
   1.107 @@ -1526,13 +1545,13 @@
   1.108  }
   1.109  
   1.110  
   1.111 -void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
   1.112 +void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
   1.113    KlassHandle  resolved_klass;
   1.114    Symbol* method_name = NULL;
   1.115    Symbol* method_signature = NULL;
   1.116    KlassHandle  current_klass;
   1.117    resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
   1.118 -  resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   1.119 +  resolve_special_call(result, recv, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
   1.120  }
   1.121  
   1.122  

mercurial