1595 final boolean doRestrict = false;
1596 final boolean checkSecurity = true;
1597 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
1598 }
1599 /** Check access and get the requested method, eliding security manager checks. */
1600 private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
1601 final boolean doRestrict = true;
1602 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
1603 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
1604 }
1605 /** Common code for all methods; do not call directly except from immediately above. */
1606 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
1607 boolean checkSecurity,
1608 boolean doRestrict, Class<?> callerClass) throws IllegalAccessException {
1609 checkMethod(refKind, refc, method);
1610 // Optionally check with the security manager; this isn't needed for unreflect* calls.
1611 if (checkSecurity)
1612 checkSecurityManager(refc, method);
1613 assert(!method.isMethodHandleInvoke());
1614
1615 Class<?> refcAsSuper;
1616 if (refKind == REF_invokeSpecial &&
1617 refc != lookupClass() &&
1618 !refc.isInterface() &&
1619 refc != (refcAsSuper = lookupClass().getSuperclass()) &&
1620 refc.isAssignableFrom(lookupClass())) {
1621 assert(!method.getName().equals("<init>")); // not this code path
1622 // Per JVMS 6.5, desc. of invokespecial instruction:
1623 // If the method is in a superclass of the LC,
1624 // and if our original search was above LC.super,
1625 // repeat the search (symbolic lookup) from LC.super.
1626 // FIXME: MemberName.resolve should handle this instead.
1627 MemberName m2 = new MemberName(refcAsSuper,
1628 method.getName(),
1629 method.getMethodType(),
1630 REF_invokeSpecial);
1631 m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
1632 if (m2 == null) throw new InternalError(method.toString());
1633 method = m2;
1634 refc = refcAsSuper;
1635 // redo basic checks
1636 checkMethod(refKind, refc, method);
1637 }
1638
1639 MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
1640 mh = maybeBindCaller(method, mh, callerClass);
1641 mh = mh.setVarargs(method);
1642 // Optionally narrow the receiver argument to refc using restrictReceiver.
1643 if (doRestrict &&
1644 (refKind == REF_invokeSpecial ||
1645 (MethodHandleNatives.refKindHasReceiver(refKind) &&
1646 restrictProtectedReceiver(method))))
1647 mh = restrictReceiver(method, mh, lookupClass());
1648 return mh;
1649 }
1650 private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
1651 Class<?> callerClass)
|
1595 final boolean doRestrict = false;
1596 final boolean checkSecurity = true;
1597 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
1598 }
1599 /** Check access and get the requested method, eliding security manager checks. */
1600 private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
1601 final boolean doRestrict = true;
1602 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
1603 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
1604 }
1605 /** Common code for all methods; do not call directly except from immediately above. */
1606 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
1607 boolean checkSecurity,
1608 boolean doRestrict, Class<?> callerClass) throws IllegalAccessException {
1609 checkMethod(refKind, refc, method);
1610 // Optionally check with the security manager; this isn't needed for unreflect* calls.
1611 if (checkSecurity)
1612 checkSecurityManager(refc, method);
1613 assert(!method.isMethodHandleInvoke());
1614
1615 if (refKind == REF_invokeSpecial &&
1616 refc != lookupClass() &&
1617 !refc.isInterface() &&
1618 refc != lookupClass().getSuperclass() &&
1619 refc.isAssignableFrom(lookupClass())) {
1620 assert(!method.getName().equals("<init>")); // not this code path
1621 // Per JVMS 6.5, desc. of invokespecial instruction:
1622 // If the method is in a superclass of the LC,
1623 // and if our original search was above LC.super,
1624 // repeat the search (symbolic lookup) from LC.super
1625 // and continue with the direct superclass of that class,
1626 // and so forth, until a match is found or no further superclasses exist.
1627 // FIXME: MemberName.resolve should handle this instead.
1628 Class<?> refcAsSuper = lookupClass();
1629 MemberName m2;
1630 do {
1631 refcAsSuper = refcAsSuper.getSuperclass();
1632 m2 = new MemberName(refcAsSuper,
1633 method.getName(),
1634 method.getMethodType(),
1635 REF_invokeSpecial);
1636 m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
1637 } while (m2 == null && // no method is found yet
1638 refc != refcAsSuper); // search up to refc
1639 if (m2 == null) throw new InternalError(method.toString());
1640 method = m2;
1641 refc = refcAsSuper;
1642 // redo basic checks
1643 checkMethod(refKind, refc, method);
1644 }
1645
1646 MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
1647 mh = maybeBindCaller(method, mh, callerClass);
1648 mh = mh.setVarargs(method);
1649 // Optionally narrow the receiver argument to refc using restrictReceiver.
1650 if (doRestrict &&
1651 (refKind == REF_invokeSpecial ||
1652 (MethodHandleNatives.refKindHasReceiver(refKind) &&
1653 restrictProtectedReceiver(method))))
1654 mh = restrictReceiver(method, mh, lookupClass());
1655 return mh;
1656 }
1657 private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh,
1658 Class<?> callerClass)
|