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             return mh.viewAsType(narrowType);


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


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



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


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