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
|