提交 031a5ed1 编写于 作者: M mchung

8004937: Improve proxy construction

Reviewed-by: jrose, ahgross
上级 61126748
...@@ -476,6 +476,8 @@ class MethodHandleNatives { ...@@ -476,6 +476,8 @@ class MethodHandleNatives {
case "getProxyClass": case "getProxyClass":
case "newProxyInstance": case "newProxyInstance":
return defc == java.lang.reflect.Proxy.class; return defc == java.lang.reflect.Proxy.class;
case "asInterfaceInstance":
return defc == java.lang.invoke.MethodHandleProxies.class;
case "getBundle": case "getBundle":
case "clearCache": case "clearCache":
return defc == java.util.ResourceBundle.class; return defc == java.util.ResourceBundle.class;
......
...@@ -141,12 +141,15 @@ public class MethodHandleProxies { ...@@ -141,12 +141,15 @@ public class MethodHandleProxies {
<T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) { <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers())) if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
throw new IllegalArgumentException("not a public interface: "+intfc.getName()); throw new IllegalArgumentException("not a public interface: "+intfc.getName());
SecurityManager smgr = System.getSecurityManager(); final MethodHandle mh;
if (smgr != null) { if (System.getSecurityManager() != null) {
final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller final int CALLER_FRAME = 2; // 0: Reflection, 1: asInterfaceInstance, 2: caller
final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME); final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
final ClassLoader ccl = caller.getClassLoader(); final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
ReflectUtil.checkProxyPackageAccess(ccl, intfc); ReflectUtil.checkProxyPackageAccess(ccl, intfc);
mh = ccl != null ? bindCaller(target, caller) : target;
} else {
mh = target;
} }
ClassLoader proxyLoader = intfc.getClassLoader(); ClassLoader proxyLoader = intfc.getClassLoader();
if (proxyLoader == null) { if (proxyLoader == null) {
...@@ -160,7 +163,7 @@ public class MethodHandleProxies { ...@@ -160,7 +163,7 @@ public class MethodHandleProxies {
for (int i = 0; i < methods.length; i++) { for (int i = 0; i < methods.length; i++) {
Method sm = methods[i]; Method sm = methods[i];
MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes()); MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
MethodHandle checkTarget = target.asType(smMT); // make throw WMT MethodHandle checkTarget = mh.asType(smMT); // make throw WMT
checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class)); checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount()); vaTargets[i] = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
} }
...@@ -183,8 +186,8 @@ public class MethodHandleProxies { ...@@ -183,8 +186,8 @@ public class MethodHandleProxies {
} }
}; };
Object proxy; final Object proxy;
if (smgr != null) { if (System.getSecurityManager() != null) {
// sun.invoke.WrapperInstance is a restricted interface not accessible // sun.invoke.WrapperInstance is a restricted interface not accessible
// by any non-null class loader. // by any non-null class loader.
final ClassLoader loader = proxyLoader; final ClassLoader loader = proxyLoader;
...@@ -204,6 +207,16 @@ public class MethodHandleProxies { ...@@ -204,6 +207,16 @@ public class MethodHandleProxies {
return intfc.cast(proxy); return intfc.cast(proxy);
} }
private static MethodHandle bindCaller(MethodHandle target, Class<?> hostClass) {
MethodHandle cbmh = MethodHandleImpl.bindCaller(target, hostClass);
if (target.isVarargsCollector()) {
MethodType type = cbmh.type();
int arity = type.parameterCount();
return cbmh.asVarargsCollector(type.parameterType(arity-1));
}
return cbmh;
}
/** /**
* Determines if the given object was produced by a call to {@link #asInterfaceInstance asInterfaceInstance}. * Determines if the given object was produced by a call to {@link #asInterfaceInstance asInterfaceInstance}.
* @param x any reference * @param x any reference
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册