equal
deleted
inserted
replaced
31 import sun.invoke.WrapperInstance; |
31 import sun.invoke.WrapperInstance; |
32 import java.util.ArrayList; |
32 import java.util.ArrayList; |
33 import sun.reflect.CallerSensitive; |
33 import sun.reflect.CallerSensitive; |
34 import sun.reflect.Reflection; |
34 import sun.reflect.Reflection; |
35 import sun.reflect.misc.ReflectUtil; |
35 import sun.reflect.misc.ReflectUtil; |
|
36 import static java.lang.invoke.MethodHandleStatics.*; |
36 |
37 |
37 /** |
38 /** |
38 * This class consists exclusively of static methods that help adapt |
39 * This class consists exclusively of static methods that help adapt |
39 * method handles to other JVM types, such as interfaces. |
40 * method handles to other JVM types, such as interfaces. |
40 */ |
41 */ |
146 // |
147 // |
147 @CallerSensitive |
148 @CallerSensitive |
148 public static |
149 public static |
149 <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) { |
150 <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) { |
150 if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers())) |
151 if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers())) |
151 throw new IllegalArgumentException("not a public interface: "+intfc.getName()); |
152 throw newIllegalArgumentException("not a public interface", intfc.getName()); |
152 final MethodHandle mh; |
153 final MethodHandle mh; |
153 if (System.getSecurityManager() != null) { |
154 if (System.getSecurityManager() != null) { |
154 final Class<?> caller = Reflection.getCallerClass(); |
155 final Class<?> caller = Reflection.getCallerClass(); |
155 final ClassLoader ccl = caller != null ? caller.getClassLoader() : null; |
156 final ClassLoader ccl = caller != null ? caller.getClassLoader() : null; |
156 ReflectUtil.checkProxyPackageAccess(ccl, intfc); |
157 ReflectUtil.checkProxyPackageAccess(ccl, intfc); |
163 ClassLoader cl = Thread.currentThread().getContextClassLoader(); // avoid use of BCP |
164 ClassLoader cl = Thread.currentThread().getContextClassLoader(); // avoid use of BCP |
164 proxyLoader = cl != null ? cl : ClassLoader.getSystemClassLoader(); |
165 proxyLoader = cl != null ? cl : ClassLoader.getSystemClassLoader(); |
165 } |
166 } |
166 final Method[] methods = getSingleNameMethods(intfc); |
167 final Method[] methods = getSingleNameMethods(intfc); |
167 if (methods == null) |
168 if (methods == null) |
168 throw new IllegalArgumentException("not a single-method interface: "+intfc.getName()); |
169 throw newIllegalArgumentException("not a single-method interface", intfc.getName()); |
169 final MethodHandle[] vaTargets = new MethodHandle[methods.length]; |
170 final MethodHandle[] vaTargets = new MethodHandle[methods.length]; |
170 for (int i = 0; i < methods.length; i++) { |
171 for (int i = 0; i < methods.length; i++) { |
171 Method sm = methods[i]; |
172 Method sm = methods[i]; |
172 MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes()); |
173 MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes()); |
173 MethodHandle checkTarget = mh.asType(smMT); // make throw WMT |
174 MethodHandle checkTarget = mh.asType(smMT); // make throw WMT |
187 } |
188 } |
188 if (method.getDeclaringClass() == WrapperInstance.class) |
189 if (method.getDeclaringClass() == WrapperInstance.class) |
189 return getArg(method.getName()); |
190 return getArg(method.getName()); |
190 if (isObjectMethod(method)) |
191 if (isObjectMethod(method)) |
191 return callObjectMethod(proxy, method, args); |
192 return callObjectMethod(proxy, method, args); |
192 throw new InternalError("bad proxy method: "+method); |
193 throw newInternalError("bad proxy method: "+method); |
193 } |
194 } |
194 }; |
195 }; |
195 |
196 |
196 final Object proxy; |
197 final Object proxy; |
197 if (System.getSecurityManager() != null) { |
198 if (System.getSecurityManager() != null) { |
238 try { |
239 try { |
239 if (x != null) |
240 if (x != null) |
240 return (WrapperInstance) x; |
241 return (WrapperInstance) x; |
241 } catch (ClassCastException ex) { |
242 } catch (ClassCastException ex) { |
242 } |
243 } |
243 throw new IllegalArgumentException("not a wrapper instance"); |
244 throw newIllegalArgumentException("not a wrapper instance"); |
244 } |
245 } |
245 |
246 |
246 /** |
247 /** |
247 * Produces or recovers a target method handle which is behaviorally |
248 * Produces or recovers a target method handle which is behaviorally |
248 * equivalent to the unique method of this wrapper instance. |
249 * equivalent to the unique method of this wrapper instance. |