jdk/src/share/classes/java/lang/invoke/MethodHandles.java
changeset 20534 da86f7904e6d
parent 20533 bee974bc42ac
child 20535 cc85c8626435
equal deleted inserted replaced
20533:bee974bc42ac 20534:da86f7904e6d
    88      * <p>
    88      * <p>
    89      * The lookup class can be changed to any other class {@code C} using an expression of the form
    89      * The lookup class can be changed to any other class {@code C} using an expression of the form
    90      * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}.
    90      * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}.
    91      * Since all classes have equal access to public names,
    91      * Since all classes have equal access to public names,
    92      * such a change would confer no new access rights.
    92      * such a change would confer no new access rights.
       
    93      * A public lookup object is always subject to
       
    94      * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
       
    95      * Also, it cannot access
       
    96      * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
    93      * @return a lookup object which is trusted minimally
    97      * @return a lookup object which is trusted minimally
    94      */
    98      */
    95     public static Lookup publicLookup() {
    99     public static Lookup publicLookup() {
    96         return Lookup.PUBLIC_LOOKUP;
   100         return Lookup.PUBLIC_LOOKUP;
    97     }
   101     }
   240      * is not symbolically accessible from the lookup class's loader,
   244      * is not symbolically accessible from the lookup class's loader,
   241      * the lookup can still succeed.
   245      * the lookup can still succeed.
   242      * For example, lookups for {@code MethodHandle.invokeExact} and
   246      * For example, lookups for {@code MethodHandle.invokeExact} and
   243      * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
   247      * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
   244      * <li>If there is a security manager installed, it can forbid the lookup
   248      * <li>If there is a security manager installed, it can forbid the lookup
   245      * on various grounds (<a href="#secmgr">see below</a>).
   249      * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
   246      * By contrast, the {@code ldc} instruction is not subject to
   250      * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
   247      * security manager checks.
   251      * constant is not subject to security manager checks.
   248      * <li>If the looked-up method has a
   252      * <li>If the looked-up method has a
   249      * <a href="MethodHandle.html#maxarity">very large arity</a>,
   253      * <a href="MethodHandle.html#maxarity">very large arity</a>,
   250      * the method handle creation may fail, due to the method handle
   254      * the method handle creation may fail, due to the method handle
   251      * type having too many parameters.
   255      * type having too many parameters.
   252      * </ul>
   256      * </ul>
   372      * <li>If the retrieved member is not public and
   376      * <li>If the retrieved member is not public and
   373      *     {@code lookc} is not present, then
   377      *     {@code lookc} is not present, then
   374      *     {@link SecurityManager#checkPermission smgr.checkPermission}
   378      *     {@link SecurityManager#checkPermission smgr.checkPermission}
   375      *     with {@code RuntimePermission("accessDeclaredMembers")} is called.
   379      *     with {@code RuntimePermission("accessDeclaredMembers")} is called.
   376      * <li>If the retrieved member is not public,
   380      * <li>If the retrieved member is not public,
       
   381      *     and if {@code lookc} is not present,
   377      *     and if {@code defc} and {@code refc} are different,
   382      *     and if {@code defc} and {@code refc} are different,
   378      *     then {@link SecurityManager#checkPackageAccess
   383      *     then {@link SecurityManager#checkPackageAccess
   379      *     smgr.checkPackageAccess(defcPkg)} is called,
   384      *     smgr.checkPackageAccess(defcPkg)} is called,
   380      *     where {@code defcPkg} is the package of {@code defc}.
   385      *     where {@code defcPkg} is the package of {@code defc}.
   381      * </ul>
   386      * </ul>
       
   387      * Security checks are performed after other access checks have passed.
       
   388      * Therefore, the above rules presuppose a member that is public,
       
   389      * or else that is being accessed from a lookup class that has
       
   390      * rights to access the member.
       
   391      *
       
   392      * <h1><a name="callsens"></a>Caller sensitive methods</h1>
       
   393      * A small number of Java methods have a special property called caller sensitivity.
       
   394      * A <em>caller-sensitive</em> method can behave differently depending on the
       
   395      * identity of its immediate caller.
       
   396      * <p>
       
   397      * If a method handle for a caller-sensitive method is requested,
       
   398      * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
       
   399      * but they take account of the lookup class in a special way.
       
   400      * The resulting method handle behaves as if it were called
       
   401      * from an instruction contained in the lookup class,
       
   402      * so that the caller-sensitive method detects the lookup class.
       
   403      * (By contrast, the invoker of the method handle is disregarded.)
       
   404      * Thus, in the case of caller-sensitive methods,
       
   405      * different lookup classes may give rise to
       
   406      * differently behaving method handles.
       
   407      * <p>
       
   408      * In cases where the lookup object is
       
   409      * {@link MethodHandles#publicLookup() publicLookup()},
       
   410      * or some other lookup object without
       
   411      * {@linkplain java.lang.invoke.MethodHandles.Lookup#PRIVATE private access},
       
   412      * the lookup class is disregarded.
       
   413      * In such cases, no caller-sensitive method handle can be created,
       
   414      * access is forbidden, and the lookup fails with an
       
   415      * {@code IllegalAccessException}.
   382      */
   416      */
   383     // FIXME in MR1: clarify that the bytecode behavior of a caller-ID method (like Class.forName) is relative to the lookupClass used to create the method handle, not the dynamic caller of the method handle
       
   384     public static final
   417     public static final
   385     class Lookup {
   418     class Lookup {
   386         /** The class on behalf of whom the lookup is being performed. */
   419         /** The class on behalf of whom the lookup is being performed. */
   387         private final Class<?> lookupClass;
   420         private final Class<?> lookupClass;
   388 
   421 
   637          * @throws NullPointerException if any argument is null
   670          * @throws NullPointerException if any argument is null
   638          */
   671          */
   639         public
   672         public
   640         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   673         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   641             MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
   674             MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
   642             checkSecurityManager(refc, method);
       
   643             return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerClass(method));
   675             return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerClass(method));
   644         }
   676         }
   645 
   677 
   646         /**
   678         /**
   647          * Produces a method handle for a virtual method.
   679          * Produces a method handle for a virtual method.
   719                 MethodHandle mh = findVirtualForMH(name, type);
   751                 MethodHandle mh = findVirtualForMH(name, type);
   720                 if (mh != null)  return mh;
   752                 if (mh != null)  return mh;
   721             }
   753             }
   722             byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
   754             byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
   723             MemberName method = resolveOrFail(refKind, refc, name, type);
   755             MemberName method = resolveOrFail(refKind, refc, name, type);
   724             checkSecurityManager(refc, method);
       
   725             return getDirectMethod(refKind, refc, method, findBoundCallerClass(method));
   756             return getDirectMethod(refKind, refc, method, findBoundCallerClass(method));
   726         }
   757         }
   727         private MethodHandle findVirtualForMH(String name, MethodType type) {
   758         private MethodHandle findVirtualForMH(String name, MethodType type) {
   728             // these names require special lookups because of the implicit MethodType argument
   759             // these names require special lookups because of the implicit MethodType argument
   729             if ("invoke".equals(name))
   760             if ("invoke".equals(name))
   780          * @throws NullPointerException if any argument is null
   811          * @throws NullPointerException if any argument is null
   781          */
   812          */
   782         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   813         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
   783             String name = "<init>";
   814             String name = "<init>";
   784             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
   815             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
   785             checkSecurityManager(refc, ctor);
       
   786             return getDirectConstructor(refc, ctor);
   816             return getDirectConstructor(refc, ctor);
   787         }
   817         }
   788 
   818 
   789         /**
   819         /**
   790          * Produces an early-bound method handle for a virtual method,
   820          * Produces an early-bound method handle for a virtual method,
   862         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
   892         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
   863                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
   893                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
   864             checkSpecialCaller(specialCaller);
   894             checkSpecialCaller(specialCaller);
   865             Lookup specialLookup = this.in(specialCaller);
   895             Lookup specialLookup = this.in(specialCaller);
   866             MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
   896             MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
   867             checkSecurityManager(refc, method);
       
   868             return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
   897             return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
   869         }
   898         }
   870 
   899 
   871         /**
   900         /**
   872          * Produces a method handle giving read access to a non-static field.
   901          * Produces a method handle giving read access to a non-static field.
   885          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   914          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   886          * @throws NullPointerException if any argument is null
   915          * @throws NullPointerException if any argument is null
   887          */
   916          */
   888         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   917         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   889             MemberName field = resolveOrFail(REF_getField, refc, name, type);
   918             MemberName field = resolveOrFail(REF_getField, refc, name, type);
   890             checkSecurityManager(refc, field);
       
   891             return getDirectField(REF_getField, refc, field);
   919             return getDirectField(REF_getField, refc, field);
   892         }
   920         }
   893 
   921 
   894         /**
   922         /**
   895          * Produces a method handle giving write access to a non-static field.
   923          * Produces a method handle giving write access to a non-static field.
   908          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   936          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   909          * @throws NullPointerException if any argument is null
   937          * @throws NullPointerException if any argument is null
   910          */
   938          */
   911         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   939         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   912             MemberName field = resolveOrFail(REF_putField, refc, name, type);
   940             MemberName field = resolveOrFail(REF_putField, refc, name, type);
   913             checkSecurityManager(refc, field);
       
   914             return getDirectField(REF_putField, refc, field);
   941             return getDirectField(REF_putField, refc, field);
   915         }
   942         }
   916 
   943 
   917         /**
   944         /**
   918          * Produces a method handle giving read access to a static field.
   945          * Produces a method handle giving read access to a static field.
   933          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   960          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   934          * @throws NullPointerException if any argument is null
   961          * @throws NullPointerException if any argument is null
   935          */
   962          */
   936         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   963         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   937             MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
   964             MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
   938             checkSecurityManager(refc, field);
       
   939             return getDirectField(REF_getStatic, refc, field);
   965             return getDirectField(REF_getStatic, refc, field);
   940         }
   966         }
   941 
   967 
   942         /**
   968         /**
   943          * Produces a method handle giving write access to a static field.
   969          * Produces a method handle giving write access to a static field.
   958          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   984          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
   959          * @throws NullPointerException if any argument is null
   985          * @throws NullPointerException if any argument is null
   960          */
   986          */
   961         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   987         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
   962             MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
   988             MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
   963             checkSecurityManager(refc, field);
       
   964             return getDirectField(REF_putStatic, refc, field);
   989             return getDirectField(REF_putStatic, refc, field);
   965         }
   990         }
   966 
   991 
   967         /**
   992         /**
   968          * Produces an early-bound method handle for a non-static method.
   993          * Produces an early-bound method handle for a non-static method.
  1011          * @throws NullPointerException if any argument is null
  1036          * @throws NullPointerException if any argument is null
  1012          */
  1037          */
  1013         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
  1038         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
  1014             Class<? extends Object> refc = receiver.getClass(); // may get NPE
  1039             Class<? extends Object> refc = receiver.getClass(); // may get NPE
  1015             MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
  1040             MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
  1016             checkSecurityManager(refc, method);
       
  1017             MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
  1041             MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
  1018             return mh.bindReceiver(receiver).setVarargs(method);
  1042             return mh.bindReceiver(receiver).setVarargs(method);
  1019         }
  1043         }
  1020 
  1044 
  1021         /**
  1045         /**
  1052             byte refKind = method.getReferenceKind();
  1076             byte refKind = method.getReferenceKind();
  1053             if (refKind == REF_invokeSpecial)
  1077             if (refKind == REF_invokeSpecial)
  1054                 refKind = REF_invokeVirtual;
  1078                 refKind = REF_invokeVirtual;
  1055             assert(method.isMethod());
  1079             assert(method.isMethod());
  1056             Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
  1080             Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
  1057             return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method));
  1081             return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method));
  1058         }
  1082         }
  1059         private MethodHandle unreflectForMH(Method m) {
  1083         private MethodHandle unreflectForMH(Method m) {
  1060             // these names require special lookups because they throw UnsupportedOperationException
  1084             // these names require special lookups because they throw UnsupportedOperationException
  1061             if (MemberName.isMethodHandleInvokeName(m.getName()))
  1085             if (MemberName.isMethodHandleInvokeName(m.getName()))
  1062                 return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m));
  1086                 return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m));
  1088             checkSpecialCaller(specialCaller);
  1112             checkSpecialCaller(specialCaller);
  1089             Lookup specialLookup = this.in(specialCaller);
  1113             Lookup specialLookup = this.in(specialCaller);
  1090             MemberName method = new MemberName(m, true);
  1114             MemberName method = new MemberName(m, true);
  1091             assert(method.isMethod());
  1115             assert(method.isMethod());
  1092             // ignore m.isAccessible:  this is a new kind of access
  1116             // ignore m.isAccessible:  this is a new kind of access
  1093             return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method));
  1117             return specialLookup.getDirectMethodNoSecurityManager(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method));
  1094         }
  1118         }
  1095 
  1119 
  1096         /**
  1120         /**
  1097          * Produces a method handle for a reflected constructor.
  1121          * Produces a method handle for a reflected constructor.
  1098          * The type of the method handle will be that of the constructor,
  1122          * The type of the method handle will be that of the constructor,
  1120         @SuppressWarnings("rawtypes")  // Will be Constructor<?> after JSR 292 MR
  1144         @SuppressWarnings("rawtypes")  // Will be Constructor<?> after JSR 292 MR
  1121         public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
  1145         public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
  1122             MemberName ctor = new MemberName(c);
  1146             MemberName ctor = new MemberName(c);
  1123             assert(ctor.isConstructor());
  1147             assert(ctor.isConstructor());
  1124             Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
  1148             Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
  1125             return lookup.getDirectConstructor(ctor.getDeclaringClass(), ctor);
  1149             return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
  1126         }
  1150         }
  1127 
  1151 
  1128         /**
  1152         /**
  1129          * Produces a method handle giving read access to a reflected field.
  1153          * Produces a method handle giving read access to a reflected field.
  1130          * The type of the method handle will have a return type of the field's
  1154          * The type of the method handle will have a return type of the field's
  1150             MemberName field = new MemberName(f, isSetter);
  1174             MemberName field = new MemberName(f, isSetter);
  1151             assert(isSetter
  1175             assert(isSetter
  1152                     ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
  1176                     ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
  1153                     : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
  1177                     : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
  1154             Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
  1178             Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
  1155             return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field);
  1179             return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
  1156         }
  1180         }
  1157 
  1181 
  1158         /**
  1182         /**
  1159          * Produces a method handle giving write access to a reflected field.
  1183          * Produces a method handle giving write access to a reflected field.
  1160          * The type of the method handle will have a void return type.
  1184          * The type of the method handle will have a void return type.
  1181          * Cracks a direct method handle created by this lookup object or a similar one.
  1205          * Cracks a direct method handle created by this lookup object or a similar one.
  1182          * Security and access checks are performed to ensure that this lookup object
  1206          * Security and access checks are performed to ensure that this lookup object
  1183          * is capable of reproducing the target method handle.
  1207          * is capable of reproducing the target method handle.
  1184          * This means that the cracking may fail if target is a direct method handle
  1208          * This means that the cracking may fail if target is a direct method handle
  1185          * but was created by an unrelated lookup object.
  1209          * but was created by an unrelated lookup object.
       
  1210          * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
       
  1211          * and was created by a lookup object for a different class.
  1186          * @param target a direct method handle to crack into symbolic reference components
  1212          * @param target a direct method handle to crack into symbolic reference components
  1187          * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
  1213          * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
  1188          * @exception SecurityException if a security manager is present and it
  1214          * @exception SecurityException if a security manager is present and it
  1189          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
  1215          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
  1190          * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
  1216          * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
  1206             if (refKind == REF_invokeVirtual && defc.isInterface())
  1232             if (refKind == REF_invokeVirtual && defc.isInterface())
  1207                 // Symbolic reference is through interface but resolves to Object method (toString, etc.)
  1233                 // Symbolic reference is through interface but resolves to Object method (toString, etc.)
  1208                 refKind = REF_invokeInterface;
  1234                 refKind = REF_invokeInterface;
  1209             // Check SM permissions and member access before cracking.
  1235             // Check SM permissions and member access before cracking.
  1210             try {
  1236             try {
       
  1237                 checkAccess(refKind, defc, member);
  1211                 checkSecurityManager(defc, member);
  1238                 checkSecurityManager(defc, member);
  1212                 checkAccess(refKind, defc, member);
       
  1213             } catch (IllegalAccessException ex) {
  1239             } catch (IllegalAccessException ex) {
  1214                 throw new IllegalArgumentException(ex);
  1240                 throw new IllegalArgumentException(ex);
       
  1241             }
       
  1242             if (allowedModes != TRUSTED && member.isCallerSensitive()) {
       
  1243                 Class<?> callerClass = target.internalCallerClass();
       
  1244                 if (!hasPrivateAccess() || callerClass != lookupClass())
       
  1245                     throw new IllegalArgumentException("method handle is caller sensitive: "+callerClass);
  1215             }
  1246             }
  1216             // Produce the handle to the results.
  1247             // Produce the handle to the results.
  1217             return new InfoFromMemberName(this, member, refKind);
  1248             return new InfoFromMemberName(this, member, refKind);
  1218         }
  1249         }
  1219 
  1250 
  1264          * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
  1295          * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
  1265          */
  1296          */
  1266         Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
  1297         Class<?> findBoundCallerClass(MemberName m) throws IllegalAccessException {
  1267             Class<?> callerClass = null;
  1298             Class<?> callerClass = null;
  1268             if (MethodHandleNatives.isCallerSensitive(m)) {
  1299             if (MethodHandleNatives.isCallerSensitive(m)) {
  1269                 // Only full-power lookup is allowed to resolve caller-sensitive methods
  1300                 // Only lookups with private access are allowed to resolve caller-sensitive methods
  1270                 if (isFullPowerLookup()) {
  1301                 if (hasPrivateAccess()) {
  1271                     callerClass = lookupClass;
  1302                     callerClass = lookupClass;
  1272                 } else {
  1303                 } else {
  1273                     throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
  1304                     throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
  1274                 }
  1305                 }
  1275             }
  1306             }
  1276             return callerClass;
  1307             return callerClass;
  1277         }
  1308         }
  1278 
  1309 
  1279         private boolean isFullPowerLookup() {
  1310         private boolean hasPrivateAccess() {
  1280             return (allowedModes & PRIVATE) != 0;
  1311             return (allowedModes & PRIVATE) != 0;
  1281         }
  1312         }
  1282 
  1313 
  1283         /**
  1314         /**
  1284          * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
  1315          * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
  1289             SecurityManager smgr = System.getSecurityManager();
  1320             SecurityManager smgr = System.getSecurityManager();
  1290             if (smgr == null)  return;
  1321             if (smgr == null)  return;
  1291             if (allowedModes == TRUSTED)  return;
  1322             if (allowedModes == TRUSTED)  return;
  1292 
  1323 
  1293             // Step 1:
  1324             // Step 1:
  1294             if (!isFullPowerLookup() ||
  1325             boolean fullPowerLookup = hasPrivateAccess();
       
  1326             if (!fullPowerLookup ||
  1295                 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
  1327                 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
  1296                 ReflectUtil.checkPackageAccess(refc);
  1328                 ReflectUtil.checkPackageAccess(refc);
  1297             }
  1329             }
  1298 
  1330 
  1299             // Step 2:
  1331             // Step 2:
  1300             if (m.isPublic()) return;
  1332             if (m.isPublic()) return;
       
  1333             if (!fullPowerLookup) {
       
  1334                 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
       
  1335             }
       
  1336 
       
  1337             // Step 3:
  1301             Class<?> defc = m.getDeclaringClass();
  1338             Class<?> defc = m.getDeclaringClass();
  1302             {
  1339             if (!fullPowerLookup && defc != refc) {
  1303                 if (!isFullPowerLookup()) {
       
  1304                     smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
       
  1305                 }
       
  1306             }
       
  1307 
       
  1308             // Step 3:
       
  1309             if (defc != refc) {
       
  1310                 ReflectUtil.checkPackageAccess(defc);
  1340                 ReflectUtil.checkPackageAccess(defc);
  1311             }
  1341             }
  1312         }
  1342         }
  1313 
  1343 
  1314         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
  1344         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
  1333             else
  1363             else
  1334                 { checkAccess(refKind, refc, m); return; }
  1364                 { checkAccess(refKind, refc, m); return; }
  1335             throw m.makeAccessException(message, this);
  1365             throw m.makeAccessException(message, this);
  1336         }
  1366         }
  1337 
  1367 
       
  1368         /** Check public/protected/private bits on the symbolic reference class and its member. */
  1338         void checkAccess(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
  1369         void checkAccess(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
  1339             assert(m.referenceKindIsConsistentWith(refKind) &&
  1370             assert(m.referenceKindIsConsistentWith(refKind) &&
  1340                    MethodHandleNatives.refKindIsValid(refKind) &&
  1371                    MethodHandleNatives.refKindIsValid(refKind) &&
  1341                    (MethodHandleNatives.refKindIsField(refKind) == m.isField()));
  1372                    (MethodHandleNatives.refKindIsField(refKind) == m.isField()));
  1342             int allowedModes = this.allowedModes;
  1373             int allowedModes = this.allowedModes;
  1407         private static final boolean ALLOW_NESTMATE_ACCESS = false;
  1438         private static final boolean ALLOW_NESTMATE_ACCESS = false;
  1408 
  1439 
  1409         private void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
  1440         private void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
  1410             int allowedModes = this.allowedModes;
  1441             int allowedModes = this.allowedModes;
  1411             if (allowedModes == TRUSTED)  return;
  1442             if (allowedModes == TRUSTED)  return;
  1412             if ((allowedModes & PRIVATE) == 0
  1443             if (!hasPrivateAccess()
  1413                 || (specialCaller != lookupClass()
  1444                 || (specialCaller != lookupClass()
  1414                     && !(ALLOW_NESTMATE_ACCESS &&
  1445                     && !(ALLOW_NESTMATE_ACCESS &&
  1415                          VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
  1446                          VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
  1416                 throw new MemberName(specialCaller).
  1447                 throw new MemberName(specialCaller).
  1417                     makeAccessException("no private access for invokespecial", this);
  1448                     makeAccessException("no private access for invokespecial", this);
  1439             if (rawType.parameterType(0) == caller)  return mh;
  1470             if (rawType.parameterType(0) == caller)  return mh;
  1440             MethodType narrowType = rawType.changeParameterType(0, caller);
  1471             MethodType narrowType = rawType.changeParameterType(0, caller);
  1441             return mh.viewAsType(narrowType);
  1472             return mh.viewAsType(narrowType);
  1442         }
  1473         }
  1443 
  1474 
       
  1475         /** Check access and get the requested method. */
  1444         private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  1476         private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  1445             return getDirectMethodCommon(refKind, refc, method,
  1477             final boolean doRestrict    = true;
  1446                     (refKind == REF_invokeSpecial ||
  1478             final boolean checkSecurity = true;
  1447                         (MethodHandleNatives.refKindHasReceiver(refKind) &&
  1479             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
  1448                             restrictProtectedReceiver(method))), callerClass);
  1480         }
  1449         }
  1481         /** Check access and get the requested method, eliding receiver narrowing rules. */
  1450         private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  1482         private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  1451             return getDirectMethodCommon(refKind, refc, method, false, callerClass);
  1483             final boolean doRestrict    = false;
  1452         }
  1484             final boolean checkSecurity = true;
       
  1485             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
       
  1486         }
       
  1487         /** Check access and get the requested method, eliding security manager checks. */
       
  1488         private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
       
  1489             final boolean doRestrict    = true;
       
  1490             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
       
  1491             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
       
  1492         }
       
  1493         /** Common code for all methods; do not call directly except from immediately above. */
  1453         private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
  1494         private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
       
  1495                                                    boolean checkSecurity,
  1454                                                    boolean doRestrict, Class<?> callerClass) throws IllegalAccessException {
  1496                                                    boolean doRestrict, Class<?> callerClass) throws IllegalAccessException {
  1455             checkMethod(refKind, refc, method);
  1497             checkMethod(refKind, refc, method);
       
  1498             // Optionally check with the security manager; this isn't needed for unreflect* calls.
       
  1499             if (checkSecurity)
       
  1500                 checkSecurityManager(refc, method);
  1456             assert(!method.isMethodHandleInvoke());
  1501             assert(!method.isMethodHandleInvoke());
  1457 
  1502 
  1458             Class<?> refcAsSuper;
  1503             Class<?> refcAsSuper;
  1459             if (refKind == REF_invokeSpecial &&
  1504             if (refKind == REF_invokeSpecial &&
  1460                 refc != lookupClass() &&
  1505                 refc != lookupClass() &&
  1480             }
  1525             }
  1481 
  1526 
  1482             MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
  1527             MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
  1483             mh = maybeBindCaller(method, mh, callerClass);
  1528             mh = maybeBindCaller(method, mh, callerClass);
  1484             mh = mh.setVarargs(method);
  1529             mh = mh.setVarargs(method);
  1485             if (doRestrict)
  1530             // Optionally narrow the receiver argument to refc using restrictReceiver.
       
  1531             if (doRestrict &&
       
  1532                    (refKind == REF_invokeSpecial ||
       
  1533                        (MethodHandleNatives.refKindHasReceiver(refKind) &&
       
  1534                            restrictProtectedReceiver(method))))
  1486                 mh = restrictReceiver(method, mh, lookupClass());
  1535                 mh = restrictReceiver(method, mh, lookupClass());
  1487             return mh;
  1536             return mh;
  1488         }
  1537         }
  1489         private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
  1538         private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
  1490                                              Class<?> callerClass)
  1539                                              Class<?> callerClass)
  1491                                              throws IllegalAccessException {
  1540                                              throws IllegalAccessException {
  1492             if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method))
  1541             if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method))
  1493                 return mh;
  1542                 return mh;
  1494             Class<?> hostClass = lookupClass;
  1543             Class<?> hostClass = lookupClass;
  1495             if ((allowedModes & PRIVATE) == 0)  // caller must use full-power lookup
  1544             if (!hasPrivateAccess())  // caller must have private access
  1496                 hostClass = callerClass;  // callerClass came from a security manager style stack walk
  1545                 hostClass = callerClass;  // callerClass came from a security manager style stack walk
  1497             MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
  1546             MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
  1498             // Note: caller will apply varargs after this step happens.
  1547             // Note: caller will apply varargs after this step happens.
  1499             return cbmh;
  1548             return cbmh;
  1500         }
  1549         }
       
  1550         /** Check access and get the requested field. */
  1501         private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
  1551         private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
       
  1552             final boolean checkSecurity = true;
       
  1553             return getDirectFieldCommon(refKind, refc, field, checkSecurity);
       
  1554         }
       
  1555         /** Check access and get the requested field, eliding security manager checks. */
       
  1556         private MethodHandle getDirectFieldNoSecurityManager(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
       
  1557             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
       
  1558             return getDirectFieldCommon(refKind, refc, field, checkSecurity);
       
  1559         }
       
  1560         /** Common code for all fields; do not call directly except from immediately above. */
       
  1561         private MethodHandle getDirectFieldCommon(byte refKind, Class<?> refc, MemberName field,
       
  1562                                                   boolean checkSecurity) throws IllegalAccessException {
  1502             checkField(refKind, refc, field);
  1563             checkField(refKind, refc, field);
       
  1564             // Optionally check with the security manager; this isn't needed for unreflect* calls.
       
  1565             if (checkSecurity)
       
  1566                 checkSecurityManager(refc, field);
  1503             MethodHandle mh = DirectMethodHandle.make(refc, field);
  1567             MethodHandle mh = DirectMethodHandle.make(refc, field);
  1504             boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
  1568             boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
  1505                                     restrictProtectedReceiver(field));
  1569                                     restrictProtectedReceiver(field));
  1506             if (doRestrict)
  1570             if (doRestrict)
  1507                 mh = restrictReceiver(field, mh, lookupClass());
  1571                 mh = restrictReceiver(field, mh, lookupClass());
  1508             return mh;
  1572             return mh;
  1509         }
  1573         }
       
  1574         /** Check access and get the requested constructor. */
  1510         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
  1575         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
       
  1576             final boolean checkSecurity = true;
       
  1577             return getDirectConstructorCommon(refc, ctor, checkSecurity);
       
  1578         }
       
  1579         /** Check access and get the requested constructor, eliding security manager checks. */
       
  1580         private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
       
  1581             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
       
  1582             return getDirectConstructorCommon(refc, ctor, checkSecurity);
       
  1583         }
       
  1584         /** Common code for all constructors; do not call directly except from immediately above. */
       
  1585         private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
       
  1586                                                   boolean checkSecurity) throws IllegalAccessException {
  1511             assert(ctor.isConstructor());
  1587             assert(ctor.isConstructor());
  1512             checkAccess(REF_newInvokeSpecial, refc, ctor);
  1588             checkAccess(REF_newInvokeSpecial, refc, ctor);
       
  1589             // Optionally check with the security manager; this isn't needed for unreflect* calls.
       
  1590             if (checkSecurity)
       
  1591                 checkSecurityManager(refc, ctor);
  1513             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
  1592             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
  1514             return DirectMethodHandle.make(ctor).setVarargs(ctor);
  1593             return DirectMethodHandle.make(ctor).setVarargs(ctor);
  1515         }
  1594         }
  1516 
  1595 
  1517         /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
  1596         /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
  1525             if (mh != null) {
  1604             if (mh != null) {
  1526                 checkSymbolicClass(defc);
  1605                 checkSymbolicClass(defc);
  1527                 return mh;
  1606                 return mh;
  1528             }
  1607             }
  1529             MemberName resolved = resolveOrFail(refKind, member);
  1608             MemberName resolved = resolveOrFail(refKind, member);
  1530             mh = getDirectMethodHandle(refKind, defc, resolved);
  1609             mh = getDirectMethodForConstant(refKind, defc, resolved);
  1531             if (mh instanceof DirectMethodHandle
  1610             if (mh instanceof DirectMethodHandle
  1532                     && canBeCached(refKind, defc, resolved)) {
  1611                     && canBeCached(refKind, defc, resolved)) {
  1533                 MemberName key = mh.internalMemberName();
  1612                 MemberName key = mh.internalMemberName();
  1534                 if (key != null) {
  1613                 if (key != null) {
  1535                     key = key.asNormalOriginal();
  1614                     key = key.asNormalOriginal();
  1571                 return false;
  1650                 return false;
  1572             }
  1651             }
  1573             return true;
  1652             return true;
  1574         }
  1653         }
  1575         private
  1654         private
  1576         MethodHandle getDirectMethodHandle(byte refKind, Class<?> defc, MemberName member) throws ReflectiveOperationException {
  1655         MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
       
  1656                 throws ReflectiveOperationException {
  1577             if (MethodHandleNatives.refKindIsField(refKind)) {
  1657             if (MethodHandleNatives.refKindIsField(refKind)) {
  1578                 return getDirectField(refKind, defc, member);
  1658                 return getDirectFieldNoSecurityManager(refKind, defc, member);
  1579             } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
  1659             } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
  1580                 return getDirectMethod(refKind, defc, member, lookupClass);
  1660                 return getDirectMethodNoSecurityManager(refKind, defc, member, lookupClass);
  1581             } else if (refKind == REF_newInvokeSpecial) {
  1661             } else if (refKind == REF_newInvokeSpecial) {
  1582                 return getDirectConstructor(defc, member);
  1662                 return getDirectConstructorNoSecurityManager(defc, member);
  1583             }
  1663             }
  1584             // oops
  1664             // oops
  1585             throw newIllegalArgumentException("bad MethodHandle constant #"+member);
  1665             throw newIllegalArgumentException("bad MethodHandle constant #"+member);
  1586         }
  1666         }
  1587 
  1667