jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
changeset 44859 5775b131af51
parent 44844 b2b4d98404ba
child 44860 a33107d3a388
equal deleted inserted replaced
44858:7183899b064b 44859:5775b131af51
  1689          * @see #findVirtual
  1689          * @see #findVirtual
  1690          */
  1690          */
  1691         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
  1691         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
  1692             Class<? extends Object> refc = receiver.getClass(); // may get NPE
  1692             Class<? extends Object> refc = receiver.getClass(); // may get NPE
  1693             MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
  1693             MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
  1694             MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
  1694             MethodHandle mh = getDirectMethodNoRestrictInvokeSpecial(refc, method, findBoundCallerClass(method));
       
  1695             if (!mh.type().leadingReferenceParameter().isAssignableFrom(receiver.getClass())) {
       
  1696                 throw new IllegalAccessException("The restricted defining class " +
       
  1697                                                  mh.type().leadingReferenceParameter().getName() +
       
  1698                                                  " is not assignable from receiver class " +
       
  1699                                                  receiver.getClass().getName());
       
  1700             }
  1695             return mh.bindArgumentL(0, receiver).setVarargs(method);
  1701             return mh.bindArgumentL(0, receiver).setVarargs(method);
  1696         }
  1702         }
  1697 
  1703 
  1698         /**
  1704         /**
  1699          * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
  1705          * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
  2238             // receiver type of mh is too wide; narrow to caller
  2244             // receiver type of mh is too wide; narrow to caller
  2239             if (!method.getDeclaringClass().isAssignableFrom(caller)) {
  2245             if (!method.getDeclaringClass().isAssignableFrom(caller)) {
  2240                 throw method.makeAccessException("caller class must be a subclass below the method", caller);
  2246                 throw method.makeAccessException("caller class must be a subclass below the method", caller);
  2241             }
  2247             }
  2242             MethodType rawType = mh.type();
  2248             MethodType rawType = mh.type();
  2243             if (rawType.parameterType(0) == caller)  return mh;
  2249             if (caller.isAssignableFrom(rawType.parameterType(0))) return mh; // no need to restrict; already narrow
  2244             MethodType narrowType = rawType.changeParameterType(0, caller);
  2250             MethodType narrowType = rawType.changeParameterType(0, caller);
  2245             assert(!mh.isVarargsCollector());  // viewAsType will lose varargs-ness
  2251             assert(!mh.isVarargsCollector());  // viewAsType will lose varargs-ness
  2246             assert(mh.viewAsTypeChecks(narrowType, true));
  2252             assert(mh.viewAsTypeChecks(narrowType, true));
  2247             return mh.copyWith(narrowType, mh.form);
  2253             return mh.copyWith(narrowType, mh.form);
  2248         }
  2254         }
  2251         private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  2257         private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  2252             final boolean doRestrict    = true;
  2258             final boolean doRestrict    = true;
  2253             final boolean checkSecurity = true;
  2259             final boolean checkSecurity = true;
  2254             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
  2260             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
  2255         }
  2261         }
  2256         /** Check access and get the requested method, eliding receiver narrowing rules. */
  2262         /** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */
  2257         private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  2263         private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  2258             final boolean doRestrict    = false;
  2264             final boolean doRestrict    = false;
  2259             final boolean checkSecurity = true;
  2265             final boolean checkSecurity = true;
  2260             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerClass);
  2266             return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerClass);
  2261         }
  2267         }
  2262         /** Check access and get the requested method, eliding security manager checks. */
  2268         /** Check access and get the requested method, eliding security manager checks. */
  2263         private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  2269         private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Class<?> callerClass) throws IllegalAccessException {
  2264             final boolean doRestrict    = true;
  2270             final boolean doRestrict    = true;
  2265             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
  2271             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
  2307             }
  2313             }
  2308 
  2314 
  2309             DirectMethodHandle dmh = DirectMethodHandle.make(refKind, refc, method);
  2315             DirectMethodHandle dmh = DirectMethodHandle.make(refKind, refc, method);
  2310             MethodHandle mh = dmh;
  2316             MethodHandle mh = dmh;
  2311             // Optionally narrow the receiver argument to refc using restrictReceiver.
  2317             // Optionally narrow the receiver argument to refc using restrictReceiver.
  2312             if (doRestrict &&
  2318             if ((doRestrict && refKind == REF_invokeSpecial) ||
  2313                    (refKind == REF_invokeSpecial ||
  2319                     (MethodHandleNatives.refKindHasReceiver(refKind) && restrictProtectedReceiver(method))) {
  2314                        (MethodHandleNatives.refKindHasReceiver(refKind) &&
       
  2315                            restrictProtectedReceiver(method)))) {
       
  2316                 mh = restrictReceiver(method, dmh, lookupClass());
  2320                 mh = restrictReceiver(method, dmh, lookupClass());
  2317             }
  2321             }
  2318             mh = maybeBindCaller(method, mh, callerClass);
  2322             mh = maybeBindCaller(method, mh, callerClass);
  2319             mh = mh.setVarargs(method);
  2323             mh = mh.setVarargs(method);
  2320             return mh;
  2324             return mh;