8004937: Improve proxy construction
Reviewed-by: jrose, ahgross
This commit is contained in:
parent
7303280ef5
commit
fad9c0e89c
@ -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 {
|
|||||||
<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 {
|
|||||||
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 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
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 {
|
|||||||
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
|
||||||
|
Loading…
Reference in New Issue
Block a user