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 |
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)) |
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. |
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)); |
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 { |
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: |
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 |