mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-20 19:14:38 +02:00
6939196: method handle signatures off the boot class path get linkage errors
Remove workaround from MethodHandleImpl lookup code; add JUnit regression test to MethodHandlesTest. Reviewed-by: twisti
This commit is contained in:
parent
0d30a781cf
commit
07ee2dd259
2 changed files with 34 additions and 21 deletions
|
@ -176,28 +176,16 @@ public abstract class MethodHandleImpl {
|
||||||
boolean doDispatch, Class<?> lookupClass) {
|
boolean doDispatch, Class<?> lookupClass) {
|
||||||
Access.check(token); // only trusted calls
|
Access.check(token); // only trusted calls
|
||||||
MethodType mtype = method.getMethodType();
|
MethodType mtype = method.getMethodType();
|
||||||
MethodType rtype = mtype;
|
|
||||||
if (!method.isStatic()) {
|
if (!method.isStatic()) {
|
||||||
// adjust the advertised receiver type to be exactly the one requested
|
// adjust the advertised receiver type to be exactly the one requested
|
||||||
// (in the case of invokespecial, this will be the calling class)
|
// (in the case of invokespecial, this will be the calling class)
|
||||||
Class<?> recvType = method.getDeclaringClass();
|
Class<?> recvType = method.getDeclaringClass();
|
||||||
mtype = mtype.insertParameterTypes(0, recvType);
|
mtype = mtype.insertParameterTypes(0, recvType);
|
||||||
// FIXME: JVM has trouble building MH.invoke sites for
|
|
||||||
// classes off the boot class path
|
|
||||||
rtype = mtype;
|
|
||||||
if (recvType.getClassLoader() != null) {
|
|
||||||
rtype = rtype.changeParameterType(0, Object.class);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass);
|
DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass);
|
||||||
if (!mh.isValid())
|
if (!mh.isValid())
|
||||||
throw newNoAccessException(method, lookupClass);
|
throw newNoAccessException(method, lookupClass);
|
||||||
if (rtype != mtype) {
|
assert(mh.type() == mtype);
|
||||||
MethodHandle rmh = AdapterMethodHandle.makePairwiseConvert(token, rtype, mh);
|
|
||||||
if (rmh == null) throw new InternalError();
|
|
||||||
return rmh;
|
|
||||||
}
|
|
||||||
assert(mh.type() == rtype);
|
|
||||||
return mh;
|
return mh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -515,10 +515,6 @@ public class MethodHandlesTest {
|
||||||
if (!positive) return; // negative test failed as expected
|
if (!positive) return; // negative test failed as expected
|
||||||
Class<?>[] paramsWithSelf = cat(array(Class[].class, (Class)defc), params);
|
Class<?>[] paramsWithSelf = cat(array(Class[].class, (Class)defc), params);
|
||||||
MethodType typeWithSelf = MethodType.methodType(ret, paramsWithSelf);
|
MethodType typeWithSelf = MethodType.methodType(ret, paramsWithSelf);
|
||||||
if (defc.getClassLoader() != null) // detune due to 6939196
|
|
||||||
assertEquals(typeWithSelf.dropParameterTypes(0,1),
|
|
||||||
target.type().dropParameterTypes(0,1));
|
|
||||||
else // FIXME: use only this test when 6939196 is fixed
|
|
||||||
assertEquals(typeWithSelf, target.type());
|
assertEquals(typeWithSelf, target.type());
|
||||||
assertTrue(target.toString().contains(methodName)); // rough check
|
assertTrue(target.toString().contains(methodName)); // rough check
|
||||||
if (!DO_MORE_CALLS && lookup != PRIVATE) return;
|
if (!DO_MORE_CALLS && lookup != PRIVATE) return;
|
||||||
|
@ -714,10 +710,6 @@ public class MethodHandlesTest {
|
||||||
if (isStatic) {
|
if (isStatic) {
|
||||||
assertEquals(typeMaybeWithSelf, target.type());
|
assertEquals(typeMaybeWithSelf, target.type());
|
||||||
} else {
|
} else {
|
||||||
if (defc.getClassLoader() != null) // detune due to 6939196
|
|
||||||
assertEquals(typeMaybeWithSelf.dropParameterTypes(0,1),
|
|
||||||
target.type().dropParameterTypes(0,1));
|
|
||||||
else // FIXME: use only this test when 6939196 is fixed
|
|
||||||
if (isSpecial)
|
if (isSpecial)
|
||||||
assertEquals(specialCaller, target.type().parameterType(0));
|
assertEquals(specialCaller, target.type().parameterType(0));
|
||||||
else
|
else
|
||||||
|
@ -1851,6 +1843,39 @@ public class MethodHandlesTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Example userMethod(Object o, String s, int i) {
|
||||||
|
called("userMethod", o, s, i);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserClassInSignature() throws Throwable {
|
||||||
|
if (CAN_SKIP_WORKING) return;
|
||||||
|
startTest("testUserClassInSignature");
|
||||||
|
Lookup lookup = MethodHandles.lookup();
|
||||||
|
String name; MethodType mt; MethodHandle mh;
|
||||||
|
Object[] args;
|
||||||
|
|
||||||
|
// Try a static method.
|
||||||
|
name = "userMethod";
|
||||||
|
mt = MethodType.methodType(Example.class, Object.class, String.class, int.class);
|
||||||
|
mh = lookup.findStatic(lookup.lookupClass(), name, mt);
|
||||||
|
assertEquals(mt, mh.type());
|
||||||
|
assertEquals(Example.class, mh.type().returnType());
|
||||||
|
args = randomArgs(mh.type().parameterArray());
|
||||||
|
mh.invokeVarargs(args);
|
||||||
|
assertCalled(name, args);
|
||||||
|
|
||||||
|
// Try a virtual method.
|
||||||
|
name = "v2";
|
||||||
|
mt = MethodType.methodType(Object.class, Object.class, int.class);
|
||||||
|
mh = lookup.findVirtual(Example.class, name, mt);
|
||||||
|
assertEquals(mt, mh.type().dropParameterTypes(0,1));
|
||||||
|
assertTrue(mh.type().parameterList().contains(Example.class));
|
||||||
|
args = randomArgs(mh.type().parameterArray());
|
||||||
|
mh.invokeVarargs(args);
|
||||||
|
assertCalled(name, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Local abbreviated copy of sun.dyn.util.ValueConversions
|
// Local abbreviated copy of sun.dyn.util.ValueConversions
|
||||||
class ValueConversions {
|
class ValueConversions {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue