Mercurial > hg > release > icedtea7-forest-2.2 > jdk
changeset 5289:203f49ff7749
8008140: Better method handle resolution
Reviewed-by: jrose, twisti, jdn
author | vlivanov |
---|---|
date | Fri, 01 Mar 2013 03:50:33 +0400 |
parents | ff8674237901 |
children | 7aa8c0da022e |
files | src/share/classes/java/lang/invoke/MethodHandles.java |
diffstat | 1 files changed, 23 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/classes/java/lang/invoke/MethodHandles.java Wed Apr 10 23:35:45 2013 +0100 +++ b/src/share/classes/java/lang/invoke/MethodHandles.java Fri Mar 01 03:50:33 2013 +0400 @@ -762,6 +762,29 @@ Class<?> callerClass, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException { checkMethod(refc, method, false); + + Class<?> refcAsSuper; + if (refc != lookupClass() && + refc != (refcAsSuper = lookupClass().getSuperclass()) && + refc.isAssignableFrom(lookupClass())) { + assert(!method.getName().equals("<init>")); // not this code path + // Per JVMS 6.5, desc. of invokespecial instruction: + // If the method is in a superclass of the LC, + // and if our original search was above LC.super, + // repeat the search (symbolic lookup) from LC.super. + // FIXME: MemberName.resolve should handle this instead. + MemberName m2 = new MemberName(refcAsSuper, + method.getName(), + method.getMethodType(), + REF_invokeSpecial); + m2 = IMPL_NAMES.resolveOrNull(m2, true, lookupClassOrNull()); + if (m2 == null) throw new InternalError(method.toString()); + method = m2; + refc = refcAsSuper; + // redo basic checks + checkMethod(refc, method, false); + } + MethodHandle mh = MethodHandleImpl.findMethod(method, false, specialCaller); mh = maybeBindCaller(method, mh, callerClass); return restrictReceiver(method, mh, specialCaller);