diff options
| author | 2016-11-02 11:11:23 +0000 | |
|---|---|---|
| committer | 2016-11-02 11:11:23 +0000 | |
| commit | bcc17bd8bb1e6375e5f39c9ec3df84c7e6b9600e (patch) | |
| tree | 10afe2faa99acf11c1e9f12b2e29cd11537d4c3a /test/957-methodhandle-transforms/src/Main.java | |
| parent | 0fe4df18f61c7a764bc1c5eea50b19d6b1ff9b1c (diff) | |
| parent | 96120f4be0a03b8637d247848e9901093ceda3a5 (diff) | |
Merge "MethodHandles: Add tests for transforms in change 598d43d0dec5925c77"
Diffstat (limited to 'test/957-methodhandle-transforms/src/Main.java')
| -rw-r--r-- | test/957-methodhandle-transforms/src/Main.java | 313 |
1 files changed, 180 insertions, 133 deletions
diff --git a/test/957-methodhandle-transforms/src/Main.java b/test/957-methodhandle-transforms/src/Main.java index e9d313b874..4a27086924 100644 --- a/test/957-methodhandle-transforms/src/Main.java +++ b/test/957-methodhandle-transforms/src/Main.java @@ -19,182 +19,229 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; import java.lang.invoke.WrongMethodTypeException; -import java.lang.invoke.Transformers.Transformer; - -import dalvik.system.EmulatedStackFrame; public class Main { - - public static void testDelegate_allTypes(boolean z, char a, short b, int c, long d, - float e, double f, String g, Object h) { - System.out.println("boolean: " + z); - System.out.println("char: " + a); - System.out.println("short: " + b); - System.out.println("int: " + c); - System.out.println("long: " + d); - System.out.println("float: " + e); - System.out.println("double: " + f); - System.out.println("String: " + g); - System.out.println("Object: " + h); - } - - public static boolean testDelegate_returnBoolean() { - return true; - } - - public static char testDelegate_returnChar() { - return 'a'; - } - - public static int testDelegate_returnInt() { - return 42; + public static void main(String[] args) throws Throwable { + testThrowException(); + testDropArguments(); + testCatchException(); + testGuardWithTest(); } - public static long testDelegate_returnLong() { - return 43; - } + public static void testThrowException() throws Throwable { + MethodHandle handle = MethodHandles.throwException(String.class, + IllegalArgumentException.class); - public static float testDelegate_returnFloat() { - return 43.0f; - } + if (handle.type().returnType() != String.class) { + System.out.println("Unexpected return type for handle: " + handle + + " [ " + handle.type() + "]"); + } - public static double testDelegate_returnDouble() { - return 43.0; + final IllegalArgumentException iae = new IllegalArgumentException("boo!"); + try { + handle.invoke(iae); + System.out.println("Expected an exception of type: java.lang.IllegalArgumentException"); + } catch (IllegalArgumentException expected) { + if (expected != iae) { + System.out.println("Wrong exception: expected " + iae + " but was " + expected); + } + } } - public static String testDelegate_returnString() { - return "plank"; + public static void dropArguments_delegate(String message, long message2) { + System.out.println("Message: " + message + ", Message2: " + message2); } - public static class DelegatingTransformer extends Transformer { - private final MethodHandle delegate; + public static void testDropArguments() throws Throwable { + MethodHandle delegate = MethodHandles.lookup().findStatic(Main.class, + "dropArguments_delegate", + MethodType.methodType(void.class, new Class<?>[] { String.class, long.class })); - public DelegatingTransformer(MethodHandle delegate) { - super(delegate.type()); - this.delegate = delegate; - } + MethodHandle transform = MethodHandles.dropArguments(delegate, 0, int.class, Object.class); - @Override - public void transform(EmulatedStackFrame stackFrame) throws Throwable { - delegate.invoke(stackFrame); + // The transformer will accept two additional arguments at position zero. + try { + transform.invokeExact("foo", 42l); + fail(); + } catch (WrongMethodTypeException expected) { } - } - - public static void main(String[] args) throws Throwable { - testThrowException(); - - testDelegation(); - } - public static void testDelegation() throws Throwable { - System.out.println("---"); - System.out.println("-- testDelegation"); - System.out.println("---"); + transform.invokeExact(45, new Object(), "foo", 42l); + transform.invoke(45, new Object(), "foo", 42l); - MethodHandle specialFunctionHandle = MethodHandles.lookup().findStatic( - Main.class, "testDelegate_allTypes", MethodType.methodType(void.class, - new Class<?>[] { boolean.class, char.class, short.class, int.class, long.class, - float.class, double.class, String.class, Object.class })); + // Additional arguments at position 1. + transform = MethodHandles.dropArguments(delegate, 1, int.class, Object.class); + transform.invokeExact("foo", 45, new Object(), 42l); + transform.invoke("foo", 45, new Object(), 42l); - DelegatingTransformer delegate = new DelegatingTransformer(specialFunctionHandle); + // Additional arguments at position 2. + transform = MethodHandles.dropArguments(delegate, 2, int.class, Object.class); + transform.invokeExact("foo", 42l, 45, new Object()); + transform.invoke("foo", 42l, 45, new Object()); - // Test an exact invoke. - // - // Note that the shorter form below doesn't work and must be - // investigated on the jack side : b/32536744 - // - // delegate.invokeExact(false, 'h', (short) 56, 72, Integer.MAX_VALUE + 42l, - // 0.56f, 100.0d, "hello", (Object) "goodbye"); + // Note that we still perform argument conversions even for the arguments that + // are subsequently dropped. + try { + transform.invoke("foo", 42l, 45l, new Object()); + fail(); + } catch (WrongMethodTypeException expected) { + } catch (IllegalArgumentException expected) { + // TODO(narayan): We currently throw the wrong type of exception here, + // it's IAE and should be WMTE instead. + } - Object obj = "goodbye"; - delegate.invokeExact(false, 'h', (short) 56, 72, Integer.MAX_VALUE + 42l, - 0.56f, 100.0d, "hello", obj); + // Invalid argument location, should not be allowed. + try { + MethodHandles.dropArguments(delegate, -1, int.class, Object.class); + fail(); + } catch (IllegalArgumentException expected) { + } - // Test a non exact invoke with one int -> long conversion and a float -> double - // conversion. - delegate.invoke(false, 'h', (short) 56, 72, 73, - 0.56f, 100.0f, "hello", "goodbye"); + // Invalid argument location, should not be allowed. + try { + MethodHandles.dropArguments(delegate, 3, int.class, Object.class); + fail(); + } catch (IllegalArgumentException expected) { + } - // Should throw a WrongMethodTypeException if the types don't align. try { - delegate.invoke(false); - throw new AssertionError("Call to invoke unexpectedly succeeded"); - } catch (WrongMethodTypeException expected) { + MethodHandles.dropArguments(delegate, 1, void.class); + fail(); + } catch (IllegalArgumentException expected) { } + } - // Test return values. + public static String testCatchException_target(String arg1, long arg2, String exceptionMessage) + throws Throwable { + if (exceptionMessage != null) { + throw new IllegalArgumentException(exceptionMessage); + } - // boolean. - MethodHandle returner = MethodHandles.lookup().findStatic( - Main.class, "testDelegate_returnBoolean", MethodType.methodType(boolean.class)); - delegate = new DelegatingTransformer(returner); + System.out.println("Target: Arg1: " + arg1 + ", Arg2: " + arg2); + return "target"; + } - System.out.println((boolean) delegate.invoke()); - System.out.println((boolean) delegate.invokeExact()); + public static String testCatchException_handler(IllegalArgumentException iae, String arg1, long arg2, + String exMsg) { + System.out.println("Handler: " + iae + ", Arg1: " + arg1 + ", Arg2: " + arg2 + ", ExMsg: " + exMsg); + return "handler1"; + } - // char. - returner = MethodHandles.lookup().findStatic( - Main.class, "testDelegate_returnChar", MethodType.methodType(char.class)); - delegate = new DelegatingTransformer(returner); + public static String testCatchException_handler2(IllegalArgumentException iae, String arg1) { + System.out.println("Handler: " + iae + ", Arg1: " + arg1); + return "handler2"; + } - System.out.println((char) delegate.invoke()); - System.out.println((char) delegate.invokeExact()); + public static void testCatchException() throws Throwable { + MethodHandle target = MethodHandles.lookup().findStatic(Main.class, + "testCatchException_target", + MethodType.methodType(String.class, new Class<?>[] { String.class, long.class, String.class })); + + MethodHandle handler = MethodHandles.lookup().findStatic(Main.class, + "testCatchException_handler", + MethodType.methodType(String.class, new Class<?>[] { IllegalArgumentException.class, + String.class, long.class, String.class })); + + MethodHandle adapter = MethodHandles.catchException(target, IllegalArgumentException.class, + handler); + + String returnVal = null; + + // These two should end up calling the target always. We're passing a null exception + // message here, which means the target will not throw. + returnVal = (String) adapter.invoke("foo", 42, null); + assertEquals("target", returnVal); + returnVal = (String) adapter.invokeExact("foo", 42l, (String) null); + assertEquals("target", returnVal); + + // We're passing a non-null exception message here, which means the target will throw, + // which in turn means that the handler must be called for the next two invokes. + returnVal = (String) adapter.invoke("foo", 42, "exceptionMessage"); + assertEquals("handler1", returnVal); + returnVal = (String) adapter.invokeExact("foo", 42l, "exceptionMessage"); + assertEquals("handler1", returnVal); + + handler = MethodHandles.lookup().findStatic(Main.class, + "testCatchException_handler2", + MethodType.methodType(String.class, new Class<?>[] { IllegalArgumentException.class, + String.class })); + adapter = MethodHandles.catchException(target, IllegalArgumentException.class, handler); + + returnVal = (String) adapter.invoke("foo", 42, "exceptionMessage"); + assertEquals("handler2", returnVal); + returnVal = (String) adapter.invokeExact("foo", 42l, "exceptionMessage"); + assertEquals("handler2", returnVal); + + // Test that the type of the invoke doesn't matter. Here we call + // IllegalArgumentException.toString() on the exception that was thrown by + // the target. + handler = MethodHandles.lookup().findVirtual(IllegalArgumentException.class, + "toString", MethodType.methodType(String.class)); + adapter = MethodHandles.catchException(target, IllegalArgumentException.class, handler); + + returnVal = (String) adapter.invoke("foo", 42, "exceptionMessage"); + assertEquals("java.lang.IllegalArgumentException: exceptionMessage", returnVal); + returnVal = (String) adapter.invokeExact("foo", 42l, "exceptionMessage2"); + assertEquals("java.lang.IllegalArgumentException: exceptionMessage2", returnVal); + } - // int. - returner = MethodHandles.lookup().findStatic( - Main.class, "testDelegate_returnInt", MethodType.methodType(int.class)); - delegate = new DelegatingTransformer(returner); + public static boolean testGuardWithTest_test(String arg1, long arg2) { + return "target".equals(arg1) && 42 == arg2; + } - System.out.println((int) delegate.invoke()); - System.out.println((int) delegate.invokeExact()); + public static String testGuardWithTest_target(String arg1, long arg2, int arg3) { + System.out.println("target: " + arg1 + ", " + arg2 + ", " + arg3); + return "target"; + } - // long. - returner = MethodHandles.lookup().findStatic( - Main.class, "testDelegate_returnLong", MethodType.methodType(long.class)); - delegate = new DelegatingTransformer(returner); + public static String testGuardWithTest_fallback(String arg1, long arg2, int arg3) { + System.out.println("fallback: " + arg1 + ", " + arg2 + ", " + arg3); + return "fallback"; + } - System.out.println((long) delegate.invoke()); - System.out.println((long) delegate.invokeExact()); + public static void testGuardWithTest() throws Throwable { + MethodHandle test = MethodHandles.lookup().findStatic(Main.class, + "testGuardWithTest_test", + MethodType.methodType(boolean.class, new Class<?>[] { String.class, long.class })); - // float. - returner = MethodHandles.lookup().findStatic( - Main.class, "testDelegate_returnFloat", MethodType.methodType(float.class)); - delegate = new DelegatingTransformer(returner); + final MethodType type = MethodType.methodType(String.class, + new Class<?>[] { String.class, long.class, int.class }); - System.out.println((float) delegate.invoke()); - System.out.println((float) delegate.invokeExact()); + final MethodHandle target = MethodHandles.lookup().findStatic(Main.class, + "testGuardWithTest_target", type); + final MethodHandle fallback = MethodHandles.lookup().findStatic(Main.class, + "testGuardWithTest_fallback", type); - // double. - returner = MethodHandles.lookup().findStatic( - Main.class, "testDelegate_returnDouble", MethodType.methodType(double.class)); - delegate = new DelegatingTransformer(returner); + MethodHandle adapter = MethodHandles.guardWithTest(test, target, fallback); - System.out.println((double) delegate.invoke()); - System.out.println((double) delegate.invokeExact()); + String returnVal = null; - // references. - returner = MethodHandles.lookup().findStatic( - Main.class, "testDelegate_returnString", MethodType.methodType(String.class)); - delegate = new DelegatingTransformer(returner); + returnVal = (String) adapter.invoke("target", 42, 56); + assertEquals("target", returnVal); + returnVal = (String) adapter.invokeExact("target", 42l, 56); + assertEquals("target", returnVal); - System.out.println((String) delegate.invoke()); - System.out.println((String) delegate.invokeExact()); + returnVal = (String) adapter.invoke("fallback", 42l, 56); + assertEquals("fallback", returnVal); + returnVal = (String) adapter.invokeExact("target", 42l, 56); + assertEquals("target", returnVal); } - public static void testThrowException() throws Throwable { - MethodHandle handle = MethodHandles.throwException(String.class, - IllegalArgumentException.class); + public static void fail() { + System.out.println("FAIL"); + Thread.dumpStack(); + } - if (handle.type().returnType() != String.class) { - System.out.println("Unexpected return type for handle: " + handle + - " [ " + handle.type() + "]"); + public static void assertEquals(String s1, String s2) { + if (s1 == s2) { + return; } - try { - handle.invoke(); - System.out.println("Expected an exception of type: java.lang.IllegalArgumentException"); - } catch (IllegalArgumentException expected) { + if (s1 != null && s2 != null && s1.equals(s2)) { + return; } + + throw new AssertionError("assertEquals s1: " + s1 + ", s2: " + s2); } } |