--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Wed Jun 01 23:56:43 2011 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Wed Jun 01 23:56:47 2011 -0700
@@ -35,6 +35,7 @@
import java.util.Arrays;
import sun.reflect.Reflection;
import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
/**
* This class consists exclusively of static methods that operate on or return
@@ -579,9 +580,18 @@
MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(refc, name, type, true);
checkSecurityManager(refc, method); // stack walk magic: do not refactor
+ return accessStatic(refc, method);
+ }
+ private
+ MethodHandle accessStatic(Class<?> refc, MemberName method) throws IllegalAccessException {
checkMethod(refc, method, true);
return MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
}
+ private
+ MethodHandle resolveStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ MemberName method = resolveOrFail(refc, name, type, true);
+ return accessStatic(refc, method);
+ }
/**
* Produces a method handle for a virtual method.
@@ -624,6 +634,13 @@
public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
MemberName method = resolveOrFail(refc, name, type, false);
checkSecurityManager(refc, method); // stack walk magic: do not refactor
+ return accessVirtual(refc, method);
+ }
+ private MethodHandle resolveVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ MemberName method = resolveOrFail(refc, name, type, false);
+ return accessVirtual(refc, method);
+ }
+ private MethodHandle accessVirtual(Class<?> refc, MemberName method) throws IllegalAccessException {
checkMethod(refc, method, false);
MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
return restrictProtectedReceiver(method, mh);
@@ -658,13 +675,21 @@
public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
String name = "<init>";
MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
+ checkSecurityManager(refc, ctor); // stack walk magic: do not refactor
+ return accessConstructor(refc, ctor);
+ }
+ private MethodHandle accessConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
assert(ctor.isConstructor());
- checkSecurityManager(refc, ctor); // stack walk magic: do not refactor
checkAccess(refc, ctor);
MethodHandle rawMH = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
MethodHandle allocMH = MethodHandleImpl.makeAllocator(rawMH);
return fixVarargs(allocMH, rawMH);
}
+ private MethodHandle resolveConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ String name = "<init>";
+ MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
+ return accessConstructor(refc, ctor);
+ }
/** Return a version of MH which matches matchMH w.r.t. isVarargsCollector. */
private static MethodHandle fixVarargs(MethodHandle mh, MethodHandle matchMH) {
@@ -720,10 +745,20 @@
checkSpecialCaller(specialCaller);
MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
checkSecurityManager(refc, method); // stack walk magic: do not refactor
+ return accessSpecial(refc, method, specialCaller);
+ }
+ private MethodHandle accessSpecial(Class<?> refc, MemberName method,
+ Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
checkMethod(refc, method, false);
MethodHandle mh = MethodHandleImpl.findMethod(method, false, specialCaller);
return restrictReceiver(method, mh, specialCaller);
}
+ private MethodHandle resolveSpecial(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
+ Class<?> specialCaller = lookupClass();
+ checkSpecialCaller(specialCaller);
+ MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
+ return accessSpecial(refc, method, specialCaller);
+ }
/**
* Produces a method handle giving read access to a non-static field.
@@ -747,6 +782,10 @@
checkSecurityManager(refc, field); // stack walk magic: do not refactor
return makeAccessor(refc, field, false, false, 0);
}
+ private MethodHandle resolveGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ MemberName field = resolveOrFail(refc, name, type, false);
+ return makeAccessor(refc, field, false, false, 0);
+ }
/**
* Produces a method handle giving write access to a non-static field.
@@ -770,6 +809,10 @@
checkSecurityManager(refc, field); // stack walk magic: do not refactor
return makeAccessor(refc, field, false, true, 0);
}
+ private MethodHandle resolveSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ MemberName field = resolveOrFail(refc, name, type, false);
+ return makeAccessor(refc, field, false, true, 0);
+ }
/**
* Produces a method handle giving read access to a static field.
@@ -792,6 +835,10 @@
checkSecurityManager(refc, field); // stack walk magic: do not refactor
return makeAccessor(refc, field, false, false, 1);
}
+ private MethodHandle resolveStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ MemberName field = resolveOrFail(refc, name, type, true);
+ return makeAccessor(refc, field, false, false, 1);
+ }
/**
* Produces a method handle giving write access to a static field.
@@ -814,6 +861,10 @@
checkSecurityManager(refc, field); // stack walk magic: do not refactor
return makeAccessor(refc, field, false, true, 1);
}
+ private MethodHandle resolveStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
+ MemberName field = resolveOrFail(refc, name, type, true);
+ return makeAccessor(refc, field, false, true, 1);
+ }
/**
* Produces an early-bound method handle for a non-static method.
@@ -1179,6 +1230,25 @@
MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
return restrictProtectedReceiver(field, mh);
}
+
+ /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
+ */
+ /*non-public*/
+ MethodHandle linkMethodHandleConstant(int refKind, Class<?> defc, String name, Object type) throws ReflectiveOperationException {
+ switch (refKind) {
+ case REF_getField: return resolveGetter( defc, name, (Class<?>) type );
+ case REF_getStatic: return resolveStaticGetter( defc, name, (Class<?>) type );
+ case REF_putField: return resolveSetter( defc, name, (Class<?>) type );
+ case REF_putStatic: return resolveStaticSetter( defc, name, (Class<?>) type );
+ case REF_invokeVirtual: return resolveVirtual( defc, name, (MethodType) type );
+ case REF_invokeStatic: return resolveStatic( defc, name, (MethodType) type );
+ case REF_invokeSpecial: return resolveSpecial( defc, name, (MethodType) type );
+ case REF_newInvokeSpecial: return resolveConstructor( defc, (MethodType) type );
+ case REF_invokeInterface: return resolveVirtual( defc, name, (MethodType) type );
+ }
+ // oops
+ throw new ReflectiveOperationException("bad MethodHandle constant #"+refKind+" "+name+" : "+type);
+ }
}
/**