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
|