src/java.base/share/classes/java/lang/invoke/MethodHandles.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/java.base/share/classes/java/lang/invoke

src/java.base/share/classes/java/lang/invoke/MethodHandles.java

Print this page
rev 10592 : 8050052: Small cleanups in java.lang.invoke code
Reviewed-by: ?
rev 10593 : 8050053: Improve caching of different invokers
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10594 : 8050166: Get rid of some package-private methods on arguments in j.l.i.MethodHandle
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10595 : 8050173: Add j.l.i.MethodHandle.copyWith(MethodType, LambdaForm)
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10596 : [mq]: 07.8050173.viewAsType.1


1562             if (!hasPrivateAccess()
1563                 || (specialCaller != lookupClass()
1564                     && !(ALLOW_NESTMATE_ACCESS &&
1565                          VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
1566                 throw new MemberName(specialCaller).
1567                     makeAccessException("no private access for invokespecial", this);
1568         }
1569 
1570         private boolean restrictProtectedReceiver(MemberName method) {
1571             // The accessing class only has the right to use a protected member
1572             // on itself or a subclass.  Enforce that restriction, from JVMS 5.4.4, etc.
1573             if (!method.isProtected() || method.isStatic()
1574                 || allowedModes == TRUSTED
1575                 || method.getDeclaringClass() == lookupClass()
1576                 || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())
1577                 || (ALLOW_NESTMATE_ACCESS &&
1578                     VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
1579                 return false;
1580             return true;
1581         }
1582         private MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws IllegalAccessException {
1583             assert(!method.isStatic());
1584             // receiver type of mh is too wide; narrow to caller
1585             if (!method.getDeclaringClass().isAssignableFrom(caller)) {
1586                 throw method.makeAccessException("caller class must be a subclass below the method", caller);
1587             }
1588             MethodType rawType = mh.type();
1589             if (rawType.parameterType(0) == caller)  return mh;
1590             MethodType narrowType = rawType.changeParameterType(0, caller);
1591             assert(!mh.isVarargsCollector());  // viewAsType will lose varargs-ness
1592             assert(mh.viewAsTypeChecks(narrowType, true));
1593             assert(mh instanceof DirectMethodHandle);  // DirectMethodHandle.copyWith
1594             return mh.copyWith(narrowType, mh.form);
1595         }
1596 
1597         /** Check access and get the requested method. */
1598         private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
1599             final boolean doRestrict    = true;
1600             final boolean checkSecurity = true;
1601             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
1602         }
1603         /** Check access and get the requested method, eliding receiver narrowing rules. */
1604         private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
1605             final boolean doRestrict    = false;
1606             final boolean checkSecurity = true;
1607             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
1608         }
1609         /** Check access and get the requested method, eliding security manager checks. */
1610         private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
1611             final boolean doRestrict    = true;
1612             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
1613             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);


1636                 // and so forth, until a match is found or no further superclasses exist.
1637                 // FIXME: MemberName.resolve should handle this instead.
1638                 Class<?> refcAsSuper = lookupClass();
1639                 MemberName m2;
1640                 do {
1641                     refcAsSuper = refcAsSuper.getSuperclass();
1642                     m2 = new MemberName(refcAsSuper,
1643                                         method.getName(),
1644                                         method.getMethodType(),
1645                                         REF_invokeSpecial);
1646                     m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
1647                 } while (m2 == null &&         // no method is found yet
1648                          refc != refcAsSuper); // search up to refc
1649                 if (m2 == null)  throw new InternalError(method.toString());
1650                 method = m2;
1651                 refc = refcAsSuper;
1652                 // redo basic checks
1653                 checkMethod(refKind, refc, method);
1654             }
1655 
1656             MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
1657             mh = maybeBindCaller(method, mh, callerClass);
1658             mh = mh.setVarargs(method);
1659             // Optionally narrow the receiver argument to refc using restrictReceiver.
1660             if (doRestrict &&
1661                    (refKind == REF_invokeSpecial ||
1662                        (MethodHandleNatives.refKindHasReceiver(refKind) &&
1663                            restrictProtectedReceiver(method))))
1664                 mh = restrictReceiver(method, mh, lookupClass());



1665             return mh;
1666         }
1667         private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
1668                                              Class<?> callerClass)
1669                                              throws IllegalAccessException {
1670             if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method))
1671                 return mh;
1672             Class<?> hostClass = lookupClass;
1673             if (!hasPrivateAccess())  // caller must have private access
1674                 hostClass = callerClass;  // callerClass came from a security manager style stack walk
1675             MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
1676             // Note: caller will apply varargs after this step happens.
1677             return cbmh;
1678         }
1679         /** Check access and get the requested field. */
1680         private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
1681             final boolean checkSecurity = true;
1682             return getDirectFieldCommon(refKind, refc, field, checkSecurity);
1683         }
1684         /** Check access and get the requested field, eliding security manager checks. */
1685         private MethodHandle getDirectFieldNoSecurityManager(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
1686             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
1687             return getDirectFieldCommon(refKind, refc, field, checkSecurity);
1688         }
1689         /** Common code for all fields; do not call directly except from immediately above. */
1690         private MethodHandle getDirectFieldCommon(byte refKind, Class<?> refc, MemberName field,
1691                                                   boolean checkSecurity) throws IllegalAccessException {
1692             checkField(refKind, refc, field);
1693             // Optionally check with the security manager; this isn't needed for unreflect* calls.
1694             if (checkSecurity)
1695                 checkSecurityManager(refc, field);
1696             MethodHandle mh = DirectMethodHandle.make(refc, field);
1697             boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
1698                                     restrictProtectedReceiver(field));
1699             if (doRestrict)
1700                 mh = restrictReceiver(field, mh, lookupClass());
1701             return mh;
1702         }
1703         /** Check access and get the requested constructor. */
1704         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
1705             final boolean checkSecurity = true;
1706             return getDirectConstructorCommon(refc, ctor, checkSecurity);
1707         }
1708         /** Check access and get the requested constructor, eliding security manager checks. */
1709         private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
1710             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
1711             return getDirectConstructorCommon(refc, ctor, checkSecurity);
1712         }
1713         /** Common code for all constructors; do not call directly except from immediately above. */
1714         private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
1715                                                   boolean checkSecurity) throws IllegalAccessException {
1716             assert(ctor.isConstructor());
1717             checkAccess(REF_newInvokeSpecial, refc, ctor);
1718             // Optionally check with the security manager; this isn't needed for unreflect* calls.
1719             if (checkSecurity)
1720                 checkSecurityManager(refc, ctor);
1721             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here




1562             if (!hasPrivateAccess()
1563                 || (specialCaller != lookupClass()
1564                     && !(ALLOW_NESTMATE_ACCESS &&
1565                          VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
1566                 throw new MemberName(specialCaller).
1567                     makeAccessException("no private access for invokespecial", this);
1568         }
1569 
1570         private boolean restrictProtectedReceiver(MemberName method) {
1571             // The accessing class only has the right to use a protected member
1572             // on itself or a subclass.  Enforce that restriction, from JVMS 5.4.4, etc.
1573             if (!method.isProtected() || method.isStatic()
1574                 || allowedModes == TRUSTED
1575                 || method.getDeclaringClass() == lookupClass()
1576                 || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())
1577                 || (ALLOW_NESTMATE_ACCESS &&
1578                     VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
1579                 return false;
1580             return true;
1581         }
1582         private MethodHandle restrictReceiver(MemberName method, DirectMethodHandle mh, Class<?> caller) throws IllegalAccessException {
1583             assert(!method.isStatic());
1584             // receiver type of mh is too wide; narrow to caller
1585             if (!method.getDeclaringClass().isAssignableFrom(caller)) {
1586                 throw method.makeAccessException("caller class must be a subclass below the method", caller);
1587             }
1588             MethodType rawType = mh.type();
1589             if (rawType.parameterType(0) == caller)  return mh;
1590             MethodType narrowType = rawType.changeParameterType(0, caller);
1591             assert(!mh.isVarargsCollector());  // viewAsType will lose varargs-ness
1592             assert(mh.viewAsTypeChecks(narrowType, true));

1593             return mh.copyWith(narrowType, mh.form);
1594         }
1595 
1596         /** Check access and get the requested method. */
1597         private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
1598             final boolean doRestrict    = true;
1599             final boolean checkSecurity = true;
1600             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
1601         }
1602         /** Check access and get the requested method, eliding receiver narrowing rules. */
1603         private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
1604             final boolean doRestrict    = false;
1605             final boolean checkSecurity = true;
1606             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
1607         }
1608         /** Check access and get the requested method, eliding security manager checks. */
1609         private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
1610             final boolean doRestrict    = true;
1611             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
1612             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);


1635                 // and so forth, until a match is found or no further superclasses exist.
1636                 // FIXME: MemberName.resolve should handle this instead.
1637                 Class<?> refcAsSuper = lookupClass();
1638                 MemberName m2;
1639                 do {
1640                     refcAsSuper = refcAsSuper.getSuperclass();
1641                     m2 = new MemberName(refcAsSuper,
1642                                         method.getName(),
1643                                         method.getMethodType(),
1644                                         REF_invokeSpecial);
1645                     m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
1646                 } while (m2 == null &&         // no method is found yet
1647                          refc != refcAsSuper); // search up to refc
1648                 if (m2 == null)  throw new InternalError(method.toString());
1649                 method = m2;
1650                 refc = refcAsSuper;
1651                 // redo basic checks
1652                 checkMethod(refKind, refc, method);
1653             }
1654 
1655             DirectMethodHandle dmh = DirectMethodHandle.make(refKind, refc, method);
1656             MethodHandle mh = dmh;

1657             // Optionally narrow the receiver argument to refc using restrictReceiver.
1658             if (doRestrict &&
1659                    (refKind == REF_invokeSpecial ||
1660                        (MethodHandleNatives.refKindHasReceiver(refKind) &&
1661                            restrictProtectedReceiver(method)))) {
1662                 mh = restrictReceiver(method, dmh, lookupClass());
1663             }
1664             mh = maybeBindCaller(method, mh, callerClass);
1665             mh = mh.setVarargs(method);
1666             return mh;
1667         }
1668         private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
1669                                              Class<?> callerClass)
1670                                              throws IllegalAccessException {
1671             if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method))
1672                 return mh;
1673             Class<?> hostClass = lookupClass;
1674             if (!hasPrivateAccess())  // caller must have private access
1675                 hostClass = callerClass;  // callerClass came from a security manager style stack walk
1676             MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
1677             // Note: caller will apply varargs after this step happens.
1678             return cbmh;
1679         }
1680         /** Check access and get the requested field. */
1681         private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
1682             final boolean checkSecurity = true;
1683             return getDirectFieldCommon(refKind, refc, field, checkSecurity);
1684         }
1685         /** Check access and get the requested field, eliding security manager checks. */
1686         private MethodHandle getDirectFieldNoSecurityManager(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
1687             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
1688             return getDirectFieldCommon(refKind, refc, field, checkSecurity);
1689         }
1690         /** Common code for all fields; do not call directly except from immediately above. */
1691         private MethodHandle getDirectFieldCommon(byte refKind, Class<?> refc, MemberName field,
1692                                                   boolean checkSecurity) throws IllegalAccessException {
1693             checkField(refKind, refc, field);
1694             // Optionally check with the security manager; this isn't needed for unreflect* calls.
1695             if (checkSecurity)
1696                 checkSecurityManager(refc, field);
1697             DirectMethodHandle dmh = DirectMethodHandle.make(refc, field);
1698             boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
1699                                     restrictProtectedReceiver(field));
1700             if (doRestrict)
1701                 return restrictReceiver(field, dmh, lookupClass());
1702             return dmh;
1703         }
1704         /** Check access and get the requested constructor. */
1705         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
1706             final boolean checkSecurity = true;
1707             return getDirectConstructorCommon(refc, ctor, checkSecurity);
1708         }
1709         /** Check access and get the requested constructor, eliding security manager checks. */
1710         private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
1711             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
1712             return getDirectConstructorCommon(refc, ctor, checkSecurity);
1713         }
1714         /** Common code for all constructors; do not call directly except from immediately above. */
1715         private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
1716                                                   boolean checkSecurity) throws IllegalAccessException {
1717             assert(ctor.isConstructor());
1718             checkAccess(REF_newInvokeSpecial, refc, ctor);
1719             // Optionally check with the security manager; this isn't needed for unreflect* calls.
1720             if (checkSecurity)
1721                 checkSecurityManager(refc, ctor);
1722             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here


src/java.base/share/classes/java/lang/invoke/MethodHandles.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File