diff options
author | 2017-01-19 20:42:23 +0000 | |
---|---|---|
committer | 2017-01-20 11:20:51 +0000 | |
commit | bcfd284e06c261efc6a05b2885c57abf25c77bcf (patch) | |
tree | e4b9d0a295358c47b20cdc2e9ed0b07c26ec9f6b | |
parent | 7af8c6a499927fbd5fdd74527ee5d3cc84b438ca (diff) |
MethodHandles: Tests for asSpreader / spreadInvoker.
Tracks libcore change 337f641cc6e323c52a9e772cb2e499a515c2b533.
Test: make test-art-host
Change-Id: Iec5fa0f9366b0ef6f5cfcc6e22618e8ab8c1ed1a
-rw-r--r-- | test/957-methodhandle-transforms/expected.txt | 31 | ||||
-rw-r--r-- | test/957-methodhandle-transforms/src/Main.java | 306 |
2 files changed, 337 insertions, 0 deletions
diff --git a/test/957-methodhandle-transforms/expected.txt b/test/957-methodhandle-transforms/expected.txt index 7540ef74f3..154051f847 100644 --- a/test/957-methodhandle-transforms/expected.txt +++ b/test/957-methodhandle-transforms/expected.txt @@ -16,3 +16,34 @@ target: target, 42, 56 fallback: fallback, 42, 56 target: target, 42, 56 target: target, 42, 56 +a: a, b:b, c: c +a: a, b:b, c: c +a: a, b:b, c: c +a: a, b:b, c: c +a: a, b:b, c: c +a: a, b:b, c: c +a: a, b:b, c: c +a: a, b:43 +a: a, b:43 +a: a, b:43 +a: a, b:43 +a: a, b:43 +a: a, b:b, c: c +a: a, b:b, c: c +a: a, b:b, c: c +a: a, b:true, c: false +a: a, b:true, c: false +a: a, b:1, c: 2, d: 3, e: 4, f:5, g: 6.0, h: 7.0 +a: a, b:1, c: 2, d: 3, e: 4, f:5, g: 6.0, h: 7.0 +a: a, b:1, c: 2, d: 51, e: 52, f:53.0, g: 54.0 +a: a, b:1, c: 2, d: 51, e: 52, f:53.0, g: 54.0 +a: a, b:1, c: 2, d: 3, e: 4, f:5.0, g:6.0 +a: a, b:1, c: 2, d: 3, e: 4, f:5.0, g:6.0 +a: a, b:1, c: 2, d: 3, e: 4.0, f:5.0 +a: a, b:1, c: 2, d: 3, e: 4.0, f:5.0 +a: a, b:1, c: 2, d: 3.0, e: 4.0 +a: a, b:1, c: 2, d: 3.0, e: 4.0 +a: a, b:1.0, c: 2.0, d: 3.0 +a: a, b:1.0, c: 2.0, d: 3.0 +a: a, b:1.0, c: 2.0 +a: a, b:1.0, c: 2.0 diff --git a/test/957-methodhandle-transforms/src/Main.java b/test/957-methodhandle-transforms/src/Main.java index eebf55fb61..3271108995 100644 --- a/test/957-methodhandle-transforms/src/Main.java +++ b/test/957-methodhandle-transforms/src/Main.java @@ -34,6 +34,8 @@ public class Main { testFilterReturnValue(); testPermuteArguments(); testInvokers(); + testSpreaders_reference(); + testSpreaders_primitive(); } public static void testThrowException() throws Throwable { @@ -921,6 +923,306 @@ public class Main { } } + public static int spreadReferences(String a, String b, String c) { + System.out.println("a: " + a + ", b:" + b + ", c: " + c); + return 42; + } + + public static int spreadReferences_Unbox(String a, int b) { + System.out.println("a: " + a + ", b:" + b); + return 43; + } + + public static void testSpreaders_reference() throws Throwable { + MethodType methodType = MethodType.methodType(int.class, + new Class<?>[] { String.class, String.class, String.class }); + MethodHandle delegate = MethodHandles.lookup().findStatic( + Main.class, "spreadReferences", methodType); + + // Basic checks on array lengths. + // + // Array size = 0 + MethodHandle mhAsSpreader = delegate.asSpreader(String[].class, 0); + int ret = (int) mhAsSpreader.invoke("a", "b", "c", new String[] {}); + assertEquals(42, ret); + // Array size = 1 + mhAsSpreader = delegate.asSpreader(String[].class, 1); + ret = (int) mhAsSpreader.invoke("a", "b", new String[] { "c" }); + assertEquals(42, ret); + // Array size = 2 + mhAsSpreader = delegate.asSpreader(String[].class, 2); + ret = (int) mhAsSpreader.invoke("a", new String[] { "b", "c" }); + assertEquals(42, ret); + // Array size = 3 + mhAsSpreader = delegate.asSpreader(String[].class, 3); + ret = (int) mhAsSpreader.invoke(new String[] { "a", "b", "c"}); + assertEquals(42, ret); + + // Exception case, array size = 4 is illegal. + try { + delegate.asSpreader(String[].class, 4); + fail(); + } catch (IllegalArgumentException expected) { + } + + // Exception case, calling with an arg of the wrong size. + // Array size = 3 + mhAsSpreader = delegate.asSpreader(String[].class, 3); + try { + ret = (int) mhAsSpreader.invoke(new String[] { "a", "b"}); + } catch (IllegalArgumentException expected) { + } + + // Various other hijinks, pass as Object[] arrays, Object etc. + mhAsSpreader = delegate.asSpreader(Object[].class, 2); + ret = (int) mhAsSpreader.invoke("a", new String[] { "b", "c" }); + assertEquals(42, ret); + + mhAsSpreader = delegate.asSpreader(Object[].class, 2); + ret = (int) mhAsSpreader.invoke("a", new Object[] { "b", "c" }); + assertEquals(42, ret); + + mhAsSpreader = delegate.asSpreader(Object[].class, 2); + ret = (int) mhAsSpreader.invoke("a", (Object) new Object[] { "b", "c" }); + assertEquals(42, ret); + + // Test implicit unboxing. + MethodType methodType2 = MethodType.methodType(int.class, + new Class<?>[] { String.class, int.class }); + MethodHandle delegate2 = MethodHandles.lookup().findStatic( + Main.class, "spreadReferences_Unbox", methodType2); + + // .. with an Integer[] array. + mhAsSpreader = delegate2.asSpreader(Integer[].class, 1); + ret = (int) mhAsSpreader.invoke("a", new Integer[] { 43 }); + assertEquals(43, ret); + + // .. with an Integer[] array declared as an Object[] argument type. + mhAsSpreader = delegate2.asSpreader(Object[].class, 1); + ret = (int) mhAsSpreader.invoke("a", new Integer[] { 43 }); + assertEquals(43, ret); + + // .. with an Object[] array. + mhAsSpreader = delegate2.asSpreader(Object[].class, 1); + ret = (int) mhAsSpreader.invoke("a", new Object[] { Integer.valueOf(43)}); + assertEquals(43, ret); + + // -- Part 2-- + // Run a subset of these tests on MethodHandles.spreadInvoker, which only accepts + // a trailing argument type of Object[]. + MethodHandle spreadInvoker = MethodHandles.spreadInvoker(methodType2, 1); + ret = (int) spreadInvoker.invoke(delegate2, "a", new Object[] { Integer.valueOf(43)}); + assertEquals(43, ret); + + ret = (int) spreadInvoker.invoke(delegate2, "a", new Integer[] { 43 }); + assertEquals(43, ret); + + // NOTE: Annoyingly, the second argument here is leadingArgCount and not + // arrayLength. + spreadInvoker = MethodHandles.spreadInvoker(methodType, 3); + ret = (int) spreadInvoker.invoke(delegate, "a", "b", "c", new String[] {}); + assertEquals(42, ret); + + spreadInvoker = MethodHandles.spreadInvoker(methodType, 0); + ret = (int) spreadInvoker.invoke(delegate, new String[] { "a", "b", "c" }); + assertEquals(42, ret); + + // Exact invokes: Double check that the expected parameter type is + // Object[] and not T[]. + try { + spreadInvoker.invokeExact(delegate, new String[] { "a", "b", "c" }); + fail(); + } catch (WrongMethodTypeException expected) { + } + + ret = (int) spreadInvoker.invoke(delegate, new Object[] { "a", "b", "c" }); + assertEquals(42, ret); + } + + public static int spreadBoolean(String a, Boolean b, boolean c) { + System.out.println("a: " + a + ", b:" + b + ", c: " + c); + return 44; + } + + public static int spreadByte(String a, Byte b, byte c, + short d, int e, long f, float g, double h) { + System.out.println("a: " + a + ", b:" + b + ", c: " + c + + ", d: " + d + ", e: " + e + ", f:" + f + ", g: " + g + + ", h: " + h); + return 45; + } + + public static int spreadChar(String a, Character b, char c, + int d, long e, float f, double g) { + System.out.println("a: " + a + ", b:" + b + ", c: " + c + + ", d: " + d + ", e: " + e + ", f:" + f + ", g: " + g); + return 46; + } + + public static int spreadShort(String a, Short b, short c, + int d, long e, float f, double g) { + System.out.println("a: " + a + ", b:" + b + ", c: " + c + + ", d: " + d + ", e: " + e + ", f:" + f + ", g:" + g); + return 47; + } + + public static int spreadInt(String a, Integer b, int c, + long d, float e, double f) { + System.out.println("a: " + a + ", b:" + b + ", c: " + c + + ", d: " + d + ", e: " + e + ", f:" + f); + return 48; + } + + public static int spreadLong(String a, Long b, long c, float d, double e) { + System.out.println("a: " + a + ", b:" + b + ", c: " + c + + ", d: " + d + ", e: " + e); + return 49; + } + + public static int spreadFloat(String a, Float b, float c, double d) { + System.out.println("a: " + a + ", b:" + b + ", c: " + c + ", d: " + d); + return 50; + } + + public static int spreadDouble(String a, Double b, double c) { + System.out.println("a: " + a + ", b:" + b + ", c: " + c); + return 51; + } + + public static void testSpreaders_primitive() throws Throwable { + // boolean[] + // --------------------- + MethodType type = MethodType.methodType(int.class, + new Class<?>[] { String.class, Boolean.class, boolean.class }); + MethodHandle delegate = MethodHandles.lookup().findStatic( + Main.class, "spreadBoolean", type); + + MethodHandle spreader = delegate.asSpreader(boolean[].class, 2); + int ret = (int) spreader.invokeExact("a", new boolean[] { true, false }); + assertEquals(44, ret); + ret = (int) spreader.invoke("a", new boolean[] { true, false }); + assertEquals(44, ret); + + // boolean can't be cast to String (the first argument to the method). + try { + delegate.asSpreader(boolean[].class, 3); + fail(); + } catch (WrongMethodTypeException expected) { + } + + // int can't be cast to boolean to supply the last argument to the method. + try { + delegate.asSpreader(int[].class, 1); + fail(); + } catch (WrongMethodTypeException expected) { + } + + // byte[] + // --------------------- + type = MethodType.methodType(int.class, + new Class<?>[] { + String.class, Byte.class, byte.class, + short.class, int.class, long.class, + float.class, double.class }); + delegate = MethodHandles.lookup().findStatic(Main.class, "spreadByte", type); + + spreader = delegate.asSpreader(byte[].class, 7); + ret = (int) spreader.invokeExact("a", + new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }); + assertEquals(45, ret); + ret = (int) spreader.invoke("a", + new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 }); + assertEquals(45, ret); + + // char[] + // --------------------- + type = MethodType.methodType(int.class, + new Class<?>[] { + String.class, Character.class,char.class, + int.class, long.class, float.class, double.class }); + delegate = MethodHandles.lookup().findStatic(Main.class, "spreadChar", type); + + spreader = delegate.asSpreader(char[].class, 6); + ret = (int) spreader.invokeExact("a", + new char[] { '1', '2', '3', '4', '5', '6' }); + assertEquals(46, ret); + ret = (int) spreader.invokeExact("a", + new char[] { '1', '2', '3', '4', '5', '6' }); + assertEquals(46, ret); + + // short[] + // --------------------- + type = MethodType.methodType(int.class, + new Class<?>[] { + String.class, Short.class, short.class, + int.class, long.class, float.class, double.class }); + delegate = MethodHandles.lookup().findStatic(Main.class, "spreadShort", type); + + spreader = delegate.asSpreader(short[].class, 6); + ret = (int) spreader.invokeExact("a", + new short[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }); + assertEquals(47, ret); + ret = (int) spreader.invoke("a", + new short[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }); + assertEquals(47, ret); + + // int[] + // --------------------- + type = MethodType.methodType(int.class, + new Class<?>[] { + String.class, Integer.class, int.class, + long.class, float.class, double.class }); + delegate = MethodHandles.lookup().findStatic(Main.class, "spreadInt", type); + + spreader = delegate.asSpreader(int[].class, 5); + ret = (int) spreader.invokeExact("a", new int[] { 1, 2, 3, 4, 5 }); + assertEquals(48, ret); + ret = (int) spreader.invokeExact("a", new int[] { 1, 2, 3, 4, 5 }); + assertEquals(48, ret); + + // long[] + // --------------------- + type = MethodType.methodType(int.class, + new Class<?>[] { + String.class, Long.class, long.class, float.class, double.class }); + delegate = MethodHandles.lookup().findStatic(Main.class, "spreadLong", type); + + spreader = delegate.asSpreader(long[].class, 4); + ret = (int) spreader.invokeExact("a", + new long[] { 0x1, 0x2, 0x3, 0x4 }); + assertEquals(49, ret); + ret = (int) spreader.invoke("a", + new long[] { 0x1, 0x2, 0x3, 0x4 }); + assertEquals(49, ret); + + // float[] + // --------------------- + type = MethodType.methodType(int.class, + new Class<?>[] { + String.class, Float.class, float.class, double.class }); + delegate = MethodHandles.lookup().findStatic(Main.class, "spreadFloat", type); + + spreader = delegate.asSpreader(float[].class, 3); + ret = (int) spreader.invokeExact("a", + new float[] { 1.0f, 2.0f, 3.0f }); + assertEquals(50, ret); + ret = (int) spreader.invokeExact("a", + new float[] { 1.0f, 2.0f, 3.0f }); + assertEquals(50, ret); + + // double[] + // --------------------- + type = MethodType.methodType(int.class, + new Class<?>[] { String.class, Double.class, double.class }); + delegate = MethodHandles.lookup().findStatic(Main.class, "spreadDouble", type); + + spreader = delegate.asSpreader(double[].class, 2); + ret = (int) spreader.invokeExact("a", new double[] { 1.0, 2.0 }); + assertEquals(51, ret); + ret = (int) spreader.invokeExact("a", new double[] { 1.0, 2.0 }); + assertEquals(51, ret); + } + public static void fail() { System.out.println("FAIL"); Thread.dumpStack(); @@ -931,6 +1233,10 @@ public class Main { Thread.dumpStack(); } + public static void assertEquals(int i1, int i2) { + if (i1 != i2) throw new AssertionError("Expected: " + i1 + " was " + i2); + } + public static void assertEquals(String s1, String s2) { if (s1 == s2) { return; |