jdk/src/share/classes/java/lang/invoke/MethodHandles.java
changeset 9780 6fc3b49cfee4
parent 9752 88ab34b6da6d
child 10082 761643c9bebd
--- 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);
+        }
     }
 
     /**