8036117: MethodHandles.catchException doesn't handle VarargsCollector right (8034120 failed)

Reviewed-by: jrose, twisti
This commit is contained in:
Vladimir Ivanov 2014-03-11 19:54:33 +04:00
parent c174f6339a
commit 9d59eb2da1
2 changed files with 67 additions and 12 deletions

View File

@ -736,16 +736,17 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
@LambdaForm.Hidden @LambdaForm.Hidden
static Object guardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher, static Object guardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher,
Object... av) throws Throwable { Object... av) throws Throwable {
// Use asFixedArity() to avoid unnecessary boxing of last argument for VarargsCollector case.
try { try {
return target.invokeWithArguments(av); return target.asFixedArity().invokeWithArguments(av);
} catch (Throwable t) { } catch (Throwable t) {
if (!exType.isInstance(t)) throw t; if (!exType.isInstance(t)) throw t;
Object[] args = prepend(t, av); return catcher.asFixedArity().invokeWithArguments(prepend(t, av));
return catcher.invokeWithArguments(args);
} }
} }
/** Prepend an element {@code elem} to an {@code array}. */ /** Prepend an element {@code elem} to an {@code array}. */
@LambdaForm.Hidden
private static Object[] prepend(Object elem, Object[] array) { private static Object[] prepend(Object elem, Object[] array) {
Object[] newArray = new Object[array.length+1]; Object[] newArray = new Object[array.length+1];
newArray[0] = elem; newArray[0] = elem;

View File

@ -72,19 +72,55 @@ public class TestCatchException {
assertEquals(x, 17); assertEquals(x, 17);
} }
final static Object masterParam = new Object();
final static Object[] masterTail = new Object[] { "str" };
static Exception masterEx = new Exception();
public static Object m1(Object o1, Object o2, Object o3, Object o4, Object o5, public static Object m1(Object o1, Object o2, Object o3, Object o4, Object o5,
Object o6, Object o7, Object o8, Object... tail) { Object o6, Object o7, Object o8, Object... tail) {
assertEquals(masterParam, o1);
assertEquals(masterParam, o2);
assertEquals(masterParam, o3);
assertEquals(masterParam, o4);
assertEquals(masterParam, o5);
assertEquals(masterParam, o6);
assertEquals(masterParam, o7);
assertEquals(masterParam, o8);
assertEquals(masterTail, tail);
return tail; return tail;
} }
public static Object m2(Exception e, Object o1, Object o2, Object o3, Object o4, public static Object m2(Exception e, Object o1, Object o2, Object o3, Object o4,
Object o5, Object o6, Object o7, Object o8, Object... tail) { Object o5, Object o6, Object o7, Object o8, Object... tail) {
assertEquals(masterEx, e);
assertEquals(masterParam, o1);
assertEquals(masterParam, o2);
assertEquals(masterParam, o3);
assertEquals(masterParam, o4);
assertEquals(masterParam, o5);
assertEquals(masterParam, o6);
assertEquals(masterParam, o7);
assertEquals(masterParam, o8);
assertEquals(masterTail, tail);
return tail; return tail;
} }
public static Object throwEx(Object o1, Object o2, Object o3, Object o4, Object o5,
Object o6, Object o7, Object o8, Object... tail) throws Exception {
assertEquals(masterParam, o1);
assertEquals(masterParam, o2);
assertEquals(masterParam, o3);
assertEquals(masterParam, o4);
assertEquals(masterParam, o5);
assertEquals(masterParam, o6);
assertEquals(masterParam, o7);
assertEquals(masterParam, o8);
assertEquals(masterTail, tail);
throw masterEx;
}
@Test @Test
public void testVarargsCollector() throws Throwable { public void testVarargsCollectorNoThrow() throws Throwable {
MethodType t1 = MethodType.methodType(Object.class, Object.class, Object.class, Object.class, Object.class, MethodType t1 = MethodType.methodType(Object.class, Object.class, Object.class, Object.class, Object.class,
Object.class, Object.class, Object.class, Object.class, Object[].class); Object.class, Object.class, Object.class, Object.class, Object[].class);
@ -92,17 +128,34 @@ public class TestCatchException {
MethodHandle target = LOOKUP.findStatic(TestCatchException.class, "m1", t1) MethodHandle target = LOOKUP.findStatic(TestCatchException.class, "m1", t1)
.asVarargsCollector(Object[].class); .asVarargsCollector(Object[].class);
MethodHandle catcher = LOOKUP.findStatic(TestCatchException.class, "m2", t2)
MethodHandle catcher = LOOKUP.findStatic(TestCatchException.class, "m2", t2); .asVarargsCollector(Object[].class);
MethodHandle gwc = MethodHandles.catchException(target, Exception.class, catcher); MethodHandle gwc = MethodHandles.catchException(target, Exception.class, catcher);
Object o = new Object(); Object o = masterParam;
Object[] obj1 = new Object[] { "str" }; Object[] obj1 = masterTail;
Object r2 = gwc.invokeExact(o, o, o, o, o, o, o, o, obj1);
assertEquals(r2, obj1);
}
@Test
public void testVarargsCollectorThrow() throws Throwable {
MethodType t1 = MethodType.methodType(Object.class, Object.class, Object.class, Object.class, Object.class,
Object.class, Object.class, Object.class, Object.class, Object[].class);
MethodType t2 = t1.insertParameterTypes(0, Exception.class);
MethodHandle target = LOOKUP.findStatic(TestCatchException.class, "throwEx", t1)
.asVarargsCollector(Object[].class);
MethodHandle catcher = LOOKUP.findStatic(TestCatchException.class, "m2", t2)
.asVarargsCollector(Object[].class);
MethodHandle gwc = MethodHandles.catchException(target, Exception.class, catcher);
Object o = masterParam;
Object[] obj1 = masterTail;
Object r1 = target.invokeExact(o, o, o, o, o, o, o, o, obj1);
Object r2 = gwc.invokeExact(o, o, o, o, o, o, o, o, obj1); Object r2 = gwc.invokeExact(o, o, o, o, o, o, o, o, obj1);
assertEquals(r1, obj1);
assertEquals(r2, obj1); assertEquals(r2, obj1);
} }
@ -110,7 +163,8 @@ public class TestCatchException {
TestCatchException test = new TestCatchException(); TestCatchException test = new TestCatchException();
test.testNoThrowPath(); test.testNoThrowPath();
test.testThrowPath(); test.testThrowPath();
test.testVarargsCollector(); test.testVarargsCollectorNoThrow();
test.testVarargsCollectorThrow();
System.out.println("TEST PASSED"); System.out.println("TEST PASSED");
} }
} }