jdk/src/share/classes/java/lang/invoke/MethodHandles.java
changeset 16906 44dfee24cb71
parent 16898 b321dfd1163f
child 18156 edb590d448c5
child 18264 286a7973575a
equal deleted inserted replaced
16905:0419f45c7761 16906:44dfee24cb71
    24  */
    24  */
    25 
    25 
    26 package java.lang.invoke;
    26 package java.lang.invoke;
    27 
    27 
    28 import java.lang.reflect.*;
    28 import java.lang.reflect.*;
       
    29 import java.security.AccessController;
       
    30 import java.security.PrivilegedAction;
       
    31 import java.util.List;
       
    32 import java.util.ArrayList;
       
    33 import java.util.Arrays;
    29 import sun.invoke.util.ValueConversions;
    34 import sun.invoke.util.ValueConversions;
    30 import sun.invoke.util.VerifyAccess;
    35 import sun.invoke.util.VerifyAccess;
    31 import sun.invoke.util.Wrapper;
    36 import sun.invoke.util.Wrapper;
    32 import java.util.List;
    37 import sun.reflect.CallerSensitive;
    33 import java.util.ArrayList;
       
    34 import java.util.Arrays;
       
    35 import sun.reflect.Reflection;
    38 import sun.reflect.Reflection;
       
    39 import sun.security.util.SecurityConstants;
    36 import static java.lang.invoke.MethodHandleStatics.*;
    40 import static java.lang.invoke.MethodHandleStatics.*;
    37 import static java.lang.invoke.MethodHandleNatives.Constants.*;
    41 import static java.lang.invoke.MethodHandleNatives.Constants.*;
    38 
    42 
    39 /**
    43 /**
    40  * This class consists exclusively of static methods that operate on or return
    44  * This class consists exclusively of static methods that operate on or return
    63      * which has the capability to access any method handle that the caller has access to,
    67      * which has the capability to access any method handle that the caller has access to,
    64      * including direct method handles to private fields and methods.
    68      * including direct method handles to private fields and methods.
    65      * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
    69      * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
    66      * Do not store it in place where untrusted code can access it.
    70      * Do not store it in place where untrusted code can access it.
    67      */
    71      */
       
    72     @CallerSensitive
    68     public static Lookup lookup() {
    73     public static Lookup lookup() {
    69         return new Lookup();
    74         return new Lookup(Reflection.getCallerClass());
    70     }
    75     }
    71 
    76 
    72     /**
    77     /**
    73      * Returns a {@link Lookup lookup object} which is trusted minimally.
    78      * Returns a {@link Lookup lookup object} which is trusted minimally.
    74      * It can only be used to create method handles to
    79      * It can only be used to create method handles to
   414 
   419 
   415         /** Embody the current class (the lookupClass) as a lookup class
   420         /** Embody the current class (the lookupClass) as a lookup class
   416          * for method handle creation.
   421          * for method handle creation.
   417          * Must be called by from a method in this package,
   422          * Must be called by from a method in this package,
   418          * which in turn is called by a method not in this package.
   423          * which in turn is called by a method not in this package.
   419          * <p>
   424          */
   420          * Also, don't make it private, lest javac interpose
   425         Lookup(Class<?> lookupClass) {
   421          * an access$N method.
   426             this(lookupClass, ALL_MODES);
   422          */
       
   423         Lookup() {
       
   424             this(getCallerClassAtEntryPoint(false), ALL_MODES);
       
   425             // make sure we haven't accidentally picked up a privileged class:
   427             // make sure we haven't accidentally picked up a privileged class:
   426             checkUnprivilegedlookupClass(lookupClass);
   428             checkUnprivilegedlookupClass(lookupClass);
   427         }
       
   428 
       
   429         Lookup(Class<?> lookupClass) {
       
   430             this(lookupClass, ALL_MODES);
       
   431         }
   429         }
   432 
   430 
   433         private Lookup(Class<?> lookupClass, int allowedModes) {
   431         private Lookup(Class<?> lookupClass, int allowedModes) {
   434             this.lookupClass = lookupClass;
   432             this.lookupClass = lookupClass;
   435             this.allowedModes = allowedModes;
   433             this.allowedModes = allowedModes;
   552                 assert(false) : cname;
   550                 assert(false) : cname;
   553                 return cname;
   551                 return cname;
   554             }
   552             }
   555         }
   553         }
   556 
   554 
   557         /* Obtain the external caller class, when called from Lookup.<init> or a first-level subroutine. */
       
   558         private static Class<?> getCallerClassAtEntryPoint(boolean inSubroutine) {
       
   559             final int CALLER_DEPTH = 4;
       
   560             //  Stack for the constructor entry point (inSubroutine=false):
       
   561             // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
       
   562             // 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
       
   563             //  The stack is slightly different for a subroutine of a Lookup.find* method:
       
   564             // 2: Lookup.*, 3: Lookup.find*.*, 4: caller
       
   565             // Note:  This should be the only use of getCallerClass in this file.
       
   566             assert(Reflection.getCallerClass(CALLER_DEPTH-2) == Lookup.class);
       
   567             assert(Reflection.getCallerClass(CALLER_DEPTH-1) == (inSubroutine ? Lookup.class : MethodHandles.class));
       
   568             return Reflection.getCallerClass(CALLER_DEPTH);
       
   569         }
       
   570 
       
   571         /**
   555         /**
   572          * Produces a method handle for a static method.
   556          * Produces a method handle for a static method.
   573          * The type of the method handle will be that of the method.
   557          * The type of the method handle will be that of the method.
   574          * (Since static methods do not take receivers, there is no
   558          * (Since static methods do not take receivers, there is no
   575          * additional receiver argument inserted into the method handle type,
   559          * additional receiver argument inserted into the method handle type,
   592          *                                is set and {@code asVarargsCollector} fails
   576          *                                is set and {@code asVarargsCollector} fails
   593          * @exception SecurityException if a security manager is present and it
   577          * @exception SecurityException if a security manager is present and it
   594          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   578          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   595          * @throws NullPointerException if any argument is null
   579          * @throws NullPointerException if any argument is null
   596          */
   580          */
       
   581         @CallerSensitive
   597         public
   582         public
   598         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   583         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   599             MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
   584             MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
   600             checkSecurityManager(refc, method);  // stack walk magic: do not refactor
   585             Class<?> callerClass = Reflection.getCallerClass();
   601             Class<?> callerClass = findBoundCallerClass(method);  // stack walk magic: do not refactor
   586             checkSecurityManager(refc, method, callerClass);
   602             return getDirectMethod(REF_invokeStatic, refc, method, callerClass);
   587             return getDirectMethod(REF_invokeStatic, refc, method,
       
   588                                    findBoundCallerClass(method, callerClass));
   603         }
   589         }
   604 
   590 
   605         /**
   591         /**
   606          * Produces a method handle for a virtual method.
   592          * Produces a method handle for a virtual method.
   607          * The type of the method handle will be that of the method,
   593          * The type of the method handle will be that of the method,
   643          *                                is set and {@code asVarargsCollector} fails
   629          *                                is set and {@code asVarargsCollector} fails
   644          * @exception SecurityException if a security manager is present and it
   630          * @exception SecurityException if a security manager is present and it
   645          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   631          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   646          * @throws NullPointerException if any argument is null
   632          * @throws NullPointerException if any argument is null
   647          */
   633          */
       
   634         @CallerSensitive
   648         public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   635         public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   649             if (refc == MethodHandle.class) {
   636             if (refc == MethodHandle.class) {
   650                 MethodHandle mh = findVirtualForMH(name, type);
   637                 MethodHandle mh = findVirtualForMH(name, type);
   651                 if (mh != null)  return mh;
   638                 if (mh != null)  return mh;
   652             }
   639             }
   653             byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
   640             byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
   654             MemberName method = resolveOrFail(refKind, refc, name, type);
   641             MemberName method = resolveOrFail(refKind, refc, name, type);
   655             checkSecurityManager(refc, method);  // stack walk magic: do not refactor
   642             Class<?> callerClass = Reflection.getCallerClass();
   656             Class<?> callerClass = findBoundCallerClass(method);
   643             checkSecurityManager(refc, method, callerClass);
   657             return getDirectMethod(refKind, refc, method, callerClass);
   644             return getDirectMethod(refKind, refc, method,
       
   645                                    findBoundCallerClass(method, callerClass));
   658         }
   646         }
   659         private MethodHandle findVirtualForMH(String name, MethodType type) {
   647         private MethodHandle findVirtualForMH(String name, MethodType type) {
   660             // these names require special lookups because of the implicit MethodType argument
   648             // these names require special lookups because of the implicit MethodType argument
   661             if ("invoke".equals(name))
   649             if ("invoke".equals(name))
   662                 return invoker(type);
   650                 return invoker(type);
   689          *                                is set and {@code asVarargsCollector} fails
   677          *                                is set and {@code asVarargsCollector} fails
   690          * @exception SecurityException if a security manager is present and it
   678          * @exception SecurityException if a security manager is present and it
   691          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   679          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   692          * @throws NullPointerException if any argument is null
   680          * @throws NullPointerException if any argument is null
   693          */
   681          */
       
   682         @CallerSensitive
   694         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   683         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   695             String name = "<init>";
   684             String name = "<init>";
   696             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
   685             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
   697             checkSecurityManager(refc, ctor);  // stack walk magic: do not refactor
   686             checkSecurityManager(refc, ctor, Reflection.getCallerClass());
   698             return getDirectConstructor(refc, ctor);
   687             return getDirectConstructor(refc, ctor);
   699         }
   688         }
   700 
   689 
   701         /**
   690         /**
   702          * Produces an early-bound method handle for a virtual method,
   691          * Produces an early-bound method handle for a virtual method,
   730          *                                is set and {@code asVarargsCollector} fails
   719          *                                is set and {@code asVarargsCollector} fails
   731          * @exception SecurityException if a security manager is present and it
   720          * @exception SecurityException if a security manager is present and it
   732          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   721          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   733          * @throws NullPointerException if any argument is null
   722          * @throws NullPointerException if any argument is null
   734          */
   723          */
       
   724         @CallerSensitive
   735         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
   725         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
   736                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
   726                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
   737             checkSpecialCaller(specialCaller);
   727             checkSpecialCaller(specialCaller);
   738             Lookup specialLookup = this.in(specialCaller);
   728             Lookup specialLookup = this.in(specialCaller);
   739             MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
   729             MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
   740             checkSecurityManager(refc, method);  // stack walk magic: do not refactor
   730             Class<?> callerClass = Reflection.getCallerClass();
   741             Class<?> callerClass = findBoundCallerClass(method);
   731             checkSecurityManager(refc, method, callerClass);
   742             return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, callerClass);
   732             return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method,
       
   733                                                  findBoundCallerClass(method, callerClass));
   743         }
   734         }
   744 
   735 
   745         /**
   736         /**
   746          * Produces a method handle giving read access to a non-static field.
   737          * Produces a method handle giving read access to a non-static field.
   747          * The type of the method handle will have a return type of the field's
   738          * The type of the method handle will have a return type of the field's
   757          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
   748          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
   758          * @exception SecurityException if a security manager is present and it
   749          * @exception SecurityException if a security manager is present and it
   759          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   750          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   760          * @throws NullPointerException if any argument is null
   751          * @throws NullPointerException if any argument is null
   761          */
   752          */
       
   753         @CallerSensitive
   762         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   754         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   763             MemberName field = resolveOrFail(REF_getField, refc, name, type);
   755             MemberName field = resolveOrFail(REF_getField, refc, name, type);
   764             checkSecurityManager(refc, field);  // stack walk magic: do not refactor
   756             checkSecurityManager(refc, field, Reflection.getCallerClass());
   765             return getDirectField(REF_getField, refc, field);
   757             return getDirectField(REF_getField, refc, field);
   766         }
   758         }
   767 
   759 
   768         /**
   760         /**
   769          * Produces a method handle giving write access to a non-static field.
   761          * Produces a method handle giving write access to a non-static field.
   780          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
   772          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
   781          * @exception SecurityException if a security manager is present and it
   773          * @exception SecurityException if a security manager is present and it
   782          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   774          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   783          * @throws NullPointerException if any argument is null
   775          * @throws NullPointerException if any argument is null
   784          */
   776          */
       
   777         @CallerSensitive
   785         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   778         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   786             MemberName field = resolveOrFail(REF_putField, refc, name, type);
   779             MemberName field = resolveOrFail(REF_putField, refc, name, type);
   787             checkSecurityManager(refc, field);  // stack walk magic: do not refactor
   780             checkSecurityManager(refc, field, Reflection.getCallerClass());
   788             return getDirectField(REF_putField, refc, field);
   781             return getDirectField(REF_putField, refc, field);
   789         }
   782         }
   790 
   783 
   791         /**
   784         /**
   792          * Produces a method handle giving read access to a static field.
   785          * Produces a method handle giving read access to a static field.
   802          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
   795          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
   803          * @exception SecurityException if a security manager is present and it
   796          * @exception SecurityException if a security manager is present and it
   804          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   797          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   805          * @throws NullPointerException if any argument is null
   798          * @throws NullPointerException if any argument is null
   806          */
   799          */
       
   800         @CallerSensitive
   807         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   801         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   808             MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
   802             MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
   809             checkSecurityManager(refc, field);  // stack walk magic: do not refactor
   803             checkSecurityManager(refc, field, Reflection.getCallerClass());
   810             return getDirectField(REF_getStatic, refc, field);
   804             return getDirectField(REF_getStatic, refc, field);
   811         }
   805         }
   812 
   806 
   813         /**
   807         /**
   814          * Produces a method handle giving write access to a static field.
   808          * Produces a method handle giving write access to a static field.
   824          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
   818          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
   825          * @exception SecurityException if a security manager is present and it
   819          * @exception SecurityException if a security manager is present and it
   826          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   820          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   827          * @throws NullPointerException if any argument is null
   821          * @throws NullPointerException if any argument is null
   828          */
   822          */
       
   823         @CallerSensitive
   829         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   824         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   830             MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
   825             MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
   831             checkSecurityManager(refc, field);  // stack walk magic: do not refactor
   826             checkSecurityManager(refc, field, Reflection.getCallerClass());
   832             return getDirectField(REF_putStatic, refc, field);
   827             return getDirectField(REF_putStatic, refc, field);
   833         }
   828         }
   834 
   829 
   835         /**
   830         /**
   836          * Produces an early-bound method handle for a non-static method.
   831          * Produces an early-bound method handle for a non-static method.
   876          *                                is set and {@code asVarargsCollector} fails
   871          *                                is set and {@code asVarargsCollector} fails
   877          * @exception SecurityException if a security manager is present and it
   872          * @exception SecurityException if a security manager is present and it
   878          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   873          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   879          * @throws NullPointerException if any argument is null
   874          * @throws NullPointerException if any argument is null
   880          */
   875          */
       
   876         @CallerSensitive
   881         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   877         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   882             Class<? extends Object> refc = receiver.getClass(); // may get NPE
   878             Class<? extends Object> refc = receiver.getClass(); // may get NPE
   883             MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
   879             MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
   884             checkSecurityManager(refc, method);  // stack walk magic: do not refactor
   880             Class<?> callerClass = Reflection.getCallerClass();
   885             Class<?> callerClass = findBoundCallerClass(method);  // stack walk magic: do not refactor
   881             checkSecurityManager(refc, method, callerClass);
   886             MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, callerClass);
   882             MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method,
       
   883                                                         findBoundCallerClass(method, callerClass));
   887             return mh.bindReceiver(receiver).setVarargs(method);
   884             return mh.bindReceiver(receiver).setVarargs(method);
   888         }
   885         }
   889 
   886 
   890         /**
   887         /**
   891          * Makes a direct method handle to <i>m</i>, if the lookup class has permission.
   888          * Makes a direct method handle to <i>m</i>, if the lookup class has permission.
   906          * @throws IllegalAccessException if access checking fails
   903          * @throws IllegalAccessException if access checking fails
   907          *                                or if the method's variable arity modifier bit
   904          *                                or if the method's variable arity modifier bit
   908          *                                is set and {@code asVarargsCollector} fails
   905          *                                is set and {@code asVarargsCollector} fails
   909          * @throws NullPointerException if the argument is null
   906          * @throws NullPointerException if the argument is null
   910          */
   907          */
       
   908         @CallerSensitive
   911         public MethodHandle unreflect(Method m) throws IllegalAccessException {
   909         public MethodHandle unreflect(Method m) throws IllegalAccessException {
   912             MemberName method = new MemberName(m);
   910             MemberName method = new MemberName(m);
   913             byte refKind = method.getReferenceKind();
   911             byte refKind = method.getReferenceKind();
   914             if (refKind == REF_invokeSpecial)
   912             if (refKind == REF_invokeSpecial)
   915                 refKind = REF_invokeVirtual;
   913                 refKind = REF_invokeVirtual;
   916             assert(method.isMethod());
   914             assert(method.isMethod());
   917             Class<?> callerClass = findBoundCallerClass(method);  // stack walk magic: do not refactor
   915             Class<?> callerClass = findBoundCallerClass(method, Reflection.getCallerClass());
   918             Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
   916             Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
   919             return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, callerClass);
   917             return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, callerClass);
   920         }
   918         }
   921 
   919 
   922         /**
   920         /**
   938          * @throws IllegalAccessException if access checking fails
   936          * @throws IllegalAccessException if access checking fails
   939          *                                or if the method's variable arity modifier bit
   937          *                                or if the method's variable arity modifier bit
   940          *                                is set and {@code asVarargsCollector} fails
   938          *                                is set and {@code asVarargsCollector} fails
   941          * @throws NullPointerException if any argument is null
   939          * @throws NullPointerException if any argument is null
   942          */
   940          */
       
   941         @CallerSensitive
   943         public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
   942         public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
   944             checkSpecialCaller(specialCaller);
   943             checkSpecialCaller(specialCaller);
   945             Lookup specialLookup = this.in(specialCaller);
   944             Lookup specialLookup = this.in(specialCaller);
   946             MemberName method = new MemberName(m, true);
   945             MemberName method = new MemberName(m, true);
   947             assert(method.isMethod());
   946             assert(method.isMethod());
   948             Class<?> callerClass = findBoundCallerClass(method);  // stack walk magic: do not refactor
   947             Class<?> callerClass = findBoundCallerClass(method, Reflection.getCallerClass());
   949             // ignore m.isAccessible:  this is a new kind of access
   948             // ignore m.isAccessible:  this is a new kind of access
   950             return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, callerClass);
   949             return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, callerClass);
   951         }
   950         }
   952 
   951 
   953         /**
   952         /**
  1048         /**
  1047         /**
  1049          * Find my trustable caller class if m is a caller sensitive method.
  1048          * Find my trustable caller class if m is a caller sensitive method.
  1050          * If this lookup object has private access, then the caller class is the lookupClass.
  1049          * If this lookup object has private access, then the caller class is the lookupClass.
  1051          * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
  1050          * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
  1052          * This is the same caller class as is used by checkSecurityManager.
  1051          * This is the same caller class as is used by checkSecurityManager.
  1053          * This function performs stack walk magic: do not refactor it.
  1052          */
  1054          */
  1053         Class<?> findBoundCallerClass(MemberName m, Class<?> callerAtEntryPoint) {
  1055         Class<?> findBoundCallerClass(MemberName m) {
       
  1056             Class<?> callerClass = null;
  1054             Class<?> callerClass = null;
  1057             if (MethodHandleNatives.isCallerSensitive(m)) {
  1055             if (MethodHandleNatives.isCallerSensitive(m)) {
  1058                 // Do not refactor this to a more "logical" place, since it is stack walk magic.
  1056                 // Do not refactor this to a more "logical" place, since it is stack walk magic.
  1059                 // Note that this is the same expression as in Step 2 below in checkSecurityManager.
  1057                 // Note that this is the same expression as in Step 2 below in checkSecurityManager.
  1060                 callerClass = ((allowedModes & PRIVATE) != 0
  1058                 callerClass = ((allowedModes & PRIVATE) != 0
  1061                                ? lookupClass  // for strong access modes, no extra check
  1059                                ? lookupClass  // for strong access modes, no extra check
  1062                                // next line does stack walk magic; do not refactor:
  1060                                : callerAtEntryPoint);
  1063                                : getCallerClassAtEntryPoint(true));
       
  1064             }
  1061             }
  1065             return callerClass;
  1062             return callerClass;
  1066         }
  1063         }
       
  1064 
       
  1065         /**
       
  1066          * Determine whether a security manager has an overridden
       
  1067          * SecurityManager.checkMemberAccess method.
       
  1068          */
       
  1069         private boolean isCheckMemberAccessOverridden(SecurityManager sm) {
       
  1070             final Class<? extends SecurityManager> cls = sm.getClass();
       
  1071             if (cls == SecurityManager.class) return false;
       
  1072 
       
  1073             try {
       
  1074                 return cls.getMethod("checkMemberAccess", Class.class, int.class).
       
  1075                     getDeclaringClass() != SecurityManager.class;
       
  1076             } catch (NoSuchMethodException e) {
       
  1077                 throw new InternalError("should not reach here");
       
  1078             }
       
  1079         }
       
  1080 
  1067         /**
  1081         /**
  1068          * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
  1082          * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
  1069          * Determines a trustable caller class to compare with refc, the symbolic reference class.
  1083          * Determines a trustable caller class to compare with refc, the symbolic reference class.
  1070          * If this lookup object has private access, then the caller class is the lookupClass.
  1084          * If this lookup object has private access, then the caller class is the lookupClass.
  1071          * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
  1085          * Otherwise, it is the caller of the currently executing public API method (e.g., findVirtual).
  1072          * This function performs stack walk magic: do not refactor it.
  1086          * This function performs stack walk magic: do not refactor it.
  1073          */
  1087          */
  1074         void checkSecurityManager(Class<?> refc, MemberName m) {
  1088         void checkSecurityManager(Class<?> refc, MemberName m, Class<?> caller) {
  1075             SecurityManager smgr = System.getSecurityManager();
  1089             SecurityManager smgr = System.getSecurityManager();
  1076             if (smgr == null)  return;
  1090             if (smgr == null)  return;
  1077             if (allowedModes == TRUSTED)  return;
  1091             if (allowedModes == TRUSTED)  return;
       
  1092 
       
  1093             final boolean overridden = isCheckMemberAccessOverridden(smgr);
  1078             // Step 1:
  1094             // Step 1:
  1079             smgr.checkMemberAccess(refc, Member.PUBLIC);
  1095             {
       
  1096                 // Default policy is to allow Member.PUBLIC; no need to check
       
  1097                 // permission if SecurityManager is the default implementation
       
  1098                 final int which = Member.PUBLIC;
       
  1099                 final Class<?> clazz = refc;
       
  1100                 if (overridden) {
       
  1101                     // Don't refactor; otherwise break the stack depth for
       
  1102                     // checkMemberAccess of subclasses of SecurityManager as specified.
       
  1103                     smgr.checkMemberAccess(clazz, which);
       
  1104                 }
       
  1105             }
       
  1106 
  1080             // Step 2:
  1107             // Step 2:
  1081             Class<?> callerClass = ((allowedModes & PRIVATE) != 0
  1108             Class<?> callerClass = ((allowedModes & PRIVATE) != 0
  1082                                     ? lookupClass  // for strong access modes, no extra check
  1109                                     ? lookupClass  // for strong access modes, no extra check
  1083                                     // next line does stack walk magic; do not refactor:
  1110                                     : caller);
  1084                                     : getCallerClassAtEntryPoint(true));
       
  1085             if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) ||
  1111             if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc) ||
  1086                 (callerClass != lookupClass &&
  1112                 (callerClass != lookupClass &&
  1087                  !VerifyAccess.classLoaderIsAncestor(callerClass, refc)))
  1113                  !VerifyAccess.classLoaderIsAncestor(callerClass, refc)))
  1088                 smgr.checkPackageAccess(VerifyAccess.getPackageName(refc));
  1114                 smgr.checkPackageAccess(VerifyAccess.getPackageName(refc));
       
  1115 
  1089             // Step 3:
  1116             // Step 3:
  1090             if (m.isPublic()) return;
  1117             if (m.isPublic()) return;
  1091             Class<?> defc = m.getDeclaringClass();
  1118             Class<?> defc = m.getDeclaringClass();
  1092             smgr.checkMemberAccess(defc, Member.DECLARED);  // STACK WALK HERE
  1119             {
       
  1120                 // Inline SecurityManager.checkMemberAccess
       
  1121                 final int which = Member.DECLARED;
       
  1122                 final Class<?> clazz = defc;
       
  1123                 if (!overridden) {
       
  1124                     if (caller.getClassLoader() != clazz.getClassLoader()) {
       
  1125                         smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
       
  1126                     }
       
  1127                 } else {
       
  1128                     // Don't refactor; otherwise break the stack depth for
       
  1129                     // checkMemberAccess of subclasses of SecurityManager as specified.
       
  1130                     smgr.checkMemberAccess(clazz, which);
       
  1131                 }
       
  1132             }
       
  1133 
  1093             // Step 4:
  1134             // Step 4:
  1094             if (defc != refc)
  1135             if (defc != refc)
  1095                 smgr.checkPackageAccess(VerifyAccess.getPackageName(defc));
  1136                 smgr.checkPackageAccess(VerifyAccess.getPackageName(defc));
  1096 
       
  1097             // Comment from SM.checkMemberAccess, where which=DECLARED:
       
  1098             /*
       
  1099              * stack depth of 4 should be the caller of one of the
       
  1100              * methods in java.lang.Class that invoke checkMember
       
  1101              * access. The stack should look like:
       
  1102              *
       
  1103              * someCaller                        [3]
       
  1104              * java.lang.Class.someReflectionAPI [2]
       
  1105              * java.lang.Class.checkMemberAccess [1]
       
  1106              * SecurityManager.checkMemberAccess [0]
       
  1107              *
       
  1108              */
       
  1109             // For us it is this stack:
       
  1110             // someCaller                        [3]
       
  1111             // Lookup.findSomeMember             [2]
       
  1112             // Lookup.checkSecurityManager       [1]
       
  1113             // SecurityManager.checkMemberAccess [0]
       
  1114         }
  1137         }
  1115 
  1138 
  1116         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
  1139         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
  1117             boolean wantStatic = (refKind == REF_invokeStatic);
  1140             boolean wantStatic = (refKind == REF_invokeStatic);
  1118             String message;
  1141             String message;