xref: /aosp_15_r20/art/test/957-methodhandle-transforms/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2016 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandle;
18*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandles;
19*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandles.Lookup;
20*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodType;
21*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.VarHandle;
22*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.WrongMethodTypeException;
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker public class Main {
main(String[] args)25*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) throws Throwable {
26*795d594fSAndroid Build Coastguard Worker     testThrowException();
27*795d594fSAndroid Build Coastguard Worker     testDropArguments();
28*795d594fSAndroid Build Coastguard Worker     testCatchException();
29*795d594fSAndroid Build Coastguard Worker     testGuardWithTest();
30*795d594fSAndroid Build Coastguard Worker     testArrayElementGetter();
31*795d594fSAndroid Build Coastguard Worker     testArrayElementSetter();
32*795d594fSAndroid Build Coastguard Worker     testIdentity();
33*795d594fSAndroid Build Coastguard Worker     testConstant();
34*795d594fSAndroid Build Coastguard Worker     testBindTo();
35*795d594fSAndroid Build Coastguard Worker     testFilterReturnValue();
36*795d594fSAndroid Build Coastguard Worker     testPermuteArguments();
37*795d594fSAndroid Build Coastguard Worker     testInvokers();
38*795d594fSAndroid Build Coastguard Worker     testSpreaders_reference();
39*795d594fSAndroid Build Coastguard Worker     testSpreaders_primitive();
40*795d594fSAndroid Build Coastguard Worker     testInvokeWithArguments();
41*795d594fSAndroid Build Coastguard Worker     testAsCollector();
42*795d594fSAndroid Build Coastguard Worker     testFilterArguments();
43*795d594fSAndroid Build Coastguard Worker     testCollectArguments();
44*795d594fSAndroid Build Coastguard Worker     testInsertArguments();
45*795d594fSAndroid Build Coastguard Worker     testFoldArguments();
46*795d594fSAndroid Build Coastguard Worker   }
47*795d594fSAndroid Build Coastguard Worker 
testThrowException()48*795d594fSAndroid Build Coastguard Worker   public static void testThrowException() throws Throwable {
49*795d594fSAndroid Build Coastguard Worker     MethodHandle handle = MethodHandles.throwException(String.class,
50*795d594fSAndroid Build Coastguard Worker         IllegalArgumentException.class);
51*795d594fSAndroid Build Coastguard Worker 
52*795d594fSAndroid Build Coastguard Worker     if (handle.type().returnType() != String.class) {
53*795d594fSAndroid Build Coastguard Worker       fail("Unexpected return type for handle: " + handle +
54*795d594fSAndroid Build Coastguard Worker           " [ " + handle.type() + "]");
55*795d594fSAndroid Build Coastguard Worker     }
56*795d594fSAndroid Build Coastguard Worker 
57*795d594fSAndroid Build Coastguard Worker     final IllegalArgumentException iae = new IllegalArgumentException("boo!");
58*795d594fSAndroid Build Coastguard Worker     try {
59*795d594fSAndroid Build Coastguard Worker       handle.invoke(iae);
60*795d594fSAndroid Build Coastguard Worker       fail("Expected an exception of type: java.lang.IllegalArgumentException");
61*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
62*795d594fSAndroid Build Coastguard Worker       if (expected != iae) {
63*795d594fSAndroid Build Coastguard Worker         fail("Wrong exception: expected " + iae + " but was " + expected);
64*795d594fSAndroid Build Coastguard Worker       }
65*795d594fSAndroid Build Coastguard Worker     }
66*795d594fSAndroid Build Coastguard Worker   }
67*795d594fSAndroid Build Coastguard Worker 
dropArguments_delegate(String message, long message2)68*795d594fSAndroid Build Coastguard Worker   public static void dropArguments_delegate(String message, long message2) {
69*795d594fSAndroid Build Coastguard Worker     System.out.println("Message: " + message + ", Message2: " + message2);
70*795d594fSAndroid Build Coastguard Worker   }
71*795d594fSAndroid Build Coastguard Worker 
testDropArguments()72*795d594fSAndroid Build Coastguard Worker   public static void testDropArguments() throws Throwable {
73*795d594fSAndroid Build Coastguard Worker     MethodHandle delegate = MethodHandles.lookup().findStatic(Main.class,
74*795d594fSAndroid Build Coastguard Worker         "dropArguments_delegate",
75*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(void.class, new Class<?>[] { String.class, long.class }));
76*795d594fSAndroid Build Coastguard Worker 
77*795d594fSAndroid Build Coastguard Worker     MethodHandle transform = MethodHandles.dropArguments(delegate, 0, int.class, Object.class);
78*795d594fSAndroid Build Coastguard Worker 
79*795d594fSAndroid Build Coastguard Worker     // The transformer will accept two additional arguments at position zero.
80*795d594fSAndroid Build Coastguard Worker     try {
81*795d594fSAndroid Build Coastguard Worker       transform.invokeExact("foo", 42l);
82*795d594fSAndroid Build Coastguard Worker       fail();
83*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
84*795d594fSAndroid Build Coastguard Worker     }
85*795d594fSAndroid Build Coastguard Worker 
86*795d594fSAndroid Build Coastguard Worker     transform.invokeExact(45, new Object(), "foo", 42l);
87*795d594fSAndroid Build Coastguard Worker     transform.invoke(45, new Object(), "foo", 42l);
88*795d594fSAndroid Build Coastguard Worker 
89*795d594fSAndroid Build Coastguard Worker     // Additional arguments at position 1.
90*795d594fSAndroid Build Coastguard Worker     transform = MethodHandles.dropArguments(delegate, 1, int.class, Object.class);
91*795d594fSAndroid Build Coastguard Worker     transform.invokeExact("foo", 45, new Object(), 42l);
92*795d594fSAndroid Build Coastguard Worker     transform.invoke("foo", 45, new Object(), 42l);
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker     // Additional arguments at position 2.
95*795d594fSAndroid Build Coastguard Worker     transform = MethodHandles.dropArguments(delegate, 2, int.class, Object.class);
96*795d594fSAndroid Build Coastguard Worker     transform.invokeExact("foo", 42l, 45, new Object());
97*795d594fSAndroid Build Coastguard Worker     transform.invoke("foo", 42l, 45, new Object());
98*795d594fSAndroid Build Coastguard Worker 
99*795d594fSAndroid Build Coastguard Worker     // Note that we still perform argument conversions even for the arguments that
100*795d594fSAndroid Build Coastguard Worker     // are subsequently dropped.
101*795d594fSAndroid Build Coastguard Worker     try {
102*795d594fSAndroid Build Coastguard Worker       transform.invoke("foo", 42l, 45l, new Object());
103*795d594fSAndroid Build Coastguard Worker       fail();
104*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
105*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
106*795d594fSAndroid Build Coastguard Worker       // TODO(narayan): We currently throw the wrong type of exception here,
107*795d594fSAndroid Build Coastguard Worker       // it's IAE and should be WMTE instead.
108*795d594fSAndroid Build Coastguard Worker     }
109*795d594fSAndroid Build Coastguard Worker 
110*795d594fSAndroid Build Coastguard Worker     // Check that asType works as expected.
111*795d594fSAndroid Build Coastguard Worker     transform = MethodHandles.dropArguments(delegate, 0, int.class, Object.class);
112*795d594fSAndroid Build Coastguard Worker     transform = transform.asType(MethodType.methodType(void.class,
113*795d594fSAndroid Build Coastguard Worker           new Class<?>[] { short.class, Object.class, String.class, long.class }));
114*795d594fSAndroid Build Coastguard Worker     transform.invokeExact((short) 45, new Object(), "foo", 42l);
115*795d594fSAndroid Build Coastguard Worker 
116*795d594fSAndroid Build Coastguard Worker     // Invalid argument location, should not be allowed.
117*795d594fSAndroid Build Coastguard Worker     try {
118*795d594fSAndroid Build Coastguard Worker       MethodHandles.dropArguments(delegate, -1, int.class, Object.class);
119*795d594fSAndroid Build Coastguard Worker       fail();
120*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
121*795d594fSAndroid Build Coastguard Worker     }
122*795d594fSAndroid Build Coastguard Worker 
123*795d594fSAndroid Build Coastguard Worker     // Invalid argument location, should not be allowed.
124*795d594fSAndroid Build Coastguard Worker     try {
125*795d594fSAndroid Build Coastguard Worker       MethodHandles.dropArguments(delegate, 3, int.class, Object.class);
126*795d594fSAndroid Build Coastguard Worker       fail();
127*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
128*795d594fSAndroid Build Coastguard Worker     }
129*795d594fSAndroid Build Coastguard Worker 
130*795d594fSAndroid Build Coastguard Worker     try {
131*795d594fSAndroid Build Coastguard Worker       MethodHandles.dropArguments(delegate, 1, void.class);
132*795d594fSAndroid Build Coastguard Worker       fail();
133*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
134*795d594fSAndroid Build Coastguard Worker     }
135*795d594fSAndroid Build Coastguard Worker   }
136*795d594fSAndroid Build Coastguard Worker 
testCatchException_target(String arg1, long arg2, String exceptionMessage)137*795d594fSAndroid Build Coastguard Worker   public static String testCatchException_target(String arg1, long arg2, String exceptionMessage)
138*795d594fSAndroid Build Coastguard Worker       throws Throwable {
139*795d594fSAndroid Build Coastguard Worker     if (exceptionMessage != null) {
140*795d594fSAndroid Build Coastguard Worker       throw new IllegalArgumentException(exceptionMessage);
141*795d594fSAndroid Build Coastguard Worker     }
142*795d594fSAndroid Build Coastguard Worker 
143*795d594fSAndroid Build Coastguard Worker     System.out.println("Target: Arg1: " + arg1 + ", Arg2: " + arg2);
144*795d594fSAndroid Build Coastguard Worker     return "target";
145*795d594fSAndroid Build Coastguard Worker   }
146*795d594fSAndroid Build Coastguard Worker 
testCatchException_handler(IllegalArgumentException iae, String arg1, long arg2, String exMsg)147*795d594fSAndroid Build Coastguard Worker   public static String testCatchException_handler(IllegalArgumentException iae, String arg1, long arg2,
148*795d594fSAndroid Build Coastguard Worker       String exMsg) {
149*795d594fSAndroid Build Coastguard Worker     System.out.println("Handler: " + iae + ", Arg1: " + arg1 + ", Arg2: " + arg2 + ", ExMsg: " + exMsg);
150*795d594fSAndroid Build Coastguard Worker     return "handler1";
151*795d594fSAndroid Build Coastguard Worker   }
152*795d594fSAndroid Build Coastguard Worker 
testCatchException_handler2(IllegalArgumentException iae, String arg1)153*795d594fSAndroid Build Coastguard Worker   public static String testCatchException_handler2(IllegalArgumentException iae, String arg1) {
154*795d594fSAndroid Build Coastguard Worker     System.out.println("Handler: " + iae + ", Arg1: " + arg1);
155*795d594fSAndroid Build Coastguard Worker     return "handler2";
156*795d594fSAndroid Build Coastguard Worker   }
157*795d594fSAndroid Build Coastguard Worker 
testCatchException()158*795d594fSAndroid Build Coastguard Worker   public static void testCatchException() throws Throwable {
159*795d594fSAndroid Build Coastguard Worker     MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
160*795d594fSAndroid Build Coastguard Worker         "testCatchException_target",
161*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(String.class, new Class<?>[] { String.class, long.class, String.class }));
162*795d594fSAndroid Build Coastguard Worker 
163*795d594fSAndroid Build Coastguard Worker     MethodHandle handler = MethodHandles.lookup().findStatic(Main.class,
164*795d594fSAndroid Build Coastguard Worker         "testCatchException_handler",
165*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(String.class, new Class<?>[] { IllegalArgumentException.class,
166*795d594fSAndroid Build Coastguard Worker             String.class, long.class, String.class }));
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker     MethodHandle adapter = MethodHandles.catchException(target, IllegalArgumentException.class,
169*795d594fSAndroid Build Coastguard Worker         handler);
170*795d594fSAndroid Build Coastguard Worker 
171*795d594fSAndroid Build Coastguard Worker     String returnVal = null;
172*795d594fSAndroid Build Coastguard Worker 
173*795d594fSAndroid Build Coastguard Worker     // These two should end up calling the target always. We're passing a null exception
174*795d594fSAndroid Build Coastguard Worker     // message here, which means the target will not throw.
175*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invoke("foo", 42, null);
176*795d594fSAndroid Build Coastguard Worker     assertEquals("target", returnVal);
177*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invokeExact("foo", 42l, (String) null);
178*795d594fSAndroid Build Coastguard Worker     assertEquals("target", returnVal);
179*795d594fSAndroid Build Coastguard Worker 
180*795d594fSAndroid Build Coastguard Worker     // We're passing a non-null exception message here, which means the target will throw,
181*795d594fSAndroid Build Coastguard Worker     // which in turn means that the handler must be called for the next two invokes.
182*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invoke("foo", 42, "exceptionMessage");
183*795d594fSAndroid Build Coastguard Worker     assertEquals("handler1", returnVal);
184*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invokeExact("foo", 42l, "exceptionMessage");
185*795d594fSAndroid Build Coastguard Worker     assertEquals("handler1", returnVal);
186*795d594fSAndroid Build Coastguard Worker 
187*795d594fSAndroid Build Coastguard Worker     handler = MethodHandles.lookup().findStatic(Main.class,
188*795d594fSAndroid Build Coastguard Worker         "testCatchException_handler2",
189*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(String.class, new Class<?>[] { IllegalArgumentException.class,
190*795d594fSAndroid Build Coastguard Worker             String.class }));
191*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.catchException(target, IllegalArgumentException.class, handler);
192*795d594fSAndroid Build Coastguard Worker 
193*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invoke("foo", 42, "exceptionMessage");
194*795d594fSAndroid Build Coastguard Worker     assertEquals("handler2", returnVal);
195*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invokeExact("foo", 42l, "exceptionMessage");
196*795d594fSAndroid Build Coastguard Worker     assertEquals("handler2", returnVal);
197*795d594fSAndroid Build Coastguard Worker 
198*795d594fSAndroid Build Coastguard Worker     // Test that the type of the invoke doesn't matter. Here we call
199*795d594fSAndroid Build Coastguard Worker     // IllegalArgumentException.toString() on the exception that was thrown by
200*795d594fSAndroid Build Coastguard Worker     // the target.
201*795d594fSAndroid Build Coastguard Worker     handler = MethodHandles.lookup().findVirtual(IllegalArgumentException.class,
202*795d594fSAndroid Build Coastguard Worker         "toString", MethodType.methodType(String.class));
203*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.catchException(target, IllegalArgumentException.class, handler);
204*795d594fSAndroid Build Coastguard Worker 
205*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invoke("foo", 42, "exceptionMessage");
206*795d594fSAndroid Build Coastguard Worker     assertEquals("java.lang.IllegalArgumentException: exceptionMessage", returnVal);
207*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invokeExact("foo", 42l, "exceptionMessage2");
208*795d594fSAndroid Build Coastguard Worker     assertEquals("java.lang.IllegalArgumentException: exceptionMessage2", returnVal);
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker     // Check that asType works as expected.
211*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.catchException(target, IllegalArgumentException.class,
212*795d594fSAndroid Build Coastguard Worker         handler);
213*795d594fSAndroid Build Coastguard Worker     adapter = adapter.asType(MethodType.methodType(String.class,
214*795d594fSAndroid Build Coastguard Worker           new Class<?>[] { String.class, int.class, String.class }));
215*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invokeExact("foo", 42, "exceptionMessage");
216*795d594fSAndroid Build Coastguard Worker     assertEquals("java.lang.IllegalArgumentException: exceptionMessage", returnVal);
217*795d594fSAndroid Build Coastguard Worker   }
218*795d594fSAndroid Build Coastguard Worker 
testGuardWithTest_test(String arg1, long arg2)219*795d594fSAndroid Build Coastguard Worker   public static boolean testGuardWithTest_test(String arg1, long arg2) {
220*795d594fSAndroid Build Coastguard Worker     return "target".equals(arg1) && 42 == arg2;
221*795d594fSAndroid Build Coastguard Worker   }
222*795d594fSAndroid Build Coastguard Worker 
testGuardWithTest_target(String arg1, long arg2, int arg3)223*795d594fSAndroid Build Coastguard Worker   public static String testGuardWithTest_target(String arg1, long arg2, int arg3) {
224*795d594fSAndroid Build Coastguard Worker     System.out.println("target: " + arg1 + ", " + arg2  + ", " + arg3);
225*795d594fSAndroid Build Coastguard Worker     return "target";
226*795d594fSAndroid Build Coastguard Worker   }
227*795d594fSAndroid Build Coastguard Worker 
testGuardWithTest_fallback(String arg1, long arg2, int arg3)228*795d594fSAndroid Build Coastguard Worker   public static String testGuardWithTest_fallback(String arg1, long arg2, int arg3) {
229*795d594fSAndroid Build Coastguard Worker     System.out.println("fallback: " + arg1 + ", " + arg2  + ", " + arg3);
230*795d594fSAndroid Build Coastguard Worker     return "fallback";
231*795d594fSAndroid Build Coastguard Worker   }
232*795d594fSAndroid Build Coastguard Worker 
testGuardWithTest()233*795d594fSAndroid Build Coastguard Worker   public static void testGuardWithTest() throws Throwable {
234*795d594fSAndroid Build Coastguard Worker     MethodHandle test = MethodHandles.lookup().findStatic(Main.class,
235*795d594fSAndroid Build Coastguard Worker         "testGuardWithTest_test",
236*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(boolean.class, new Class<?>[] { String.class, long.class }));
237*795d594fSAndroid Build Coastguard Worker 
238*795d594fSAndroid Build Coastguard Worker     final MethodType type = MethodType.methodType(String.class,
239*795d594fSAndroid Build Coastguard Worker         new Class<?>[] { String.class, long.class, int.class });
240*795d594fSAndroid Build Coastguard Worker 
241*795d594fSAndroid Build Coastguard Worker     final MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
242*795d594fSAndroid Build Coastguard Worker         "testGuardWithTest_target", type);
243*795d594fSAndroid Build Coastguard Worker     final MethodHandle fallback = MethodHandles.lookup().findStatic(Main.class,
244*795d594fSAndroid Build Coastguard Worker         "testGuardWithTest_fallback", type);
245*795d594fSAndroid Build Coastguard Worker 
246*795d594fSAndroid Build Coastguard Worker     MethodHandle adapter = MethodHandles.guardWithTest(test, target, fallback);
247*795d594fSAndroid Build Coastguard Worker 
248*795d594fSAndroid Build Coastguard Worker     String returnVal = null;
249*795d594fSAndroid Build Coastguard Worker 
250*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invoke("target", 42, 56);
251*795d594fSAndroid Build Coastguard Worker     assertEquals("target", returnVal);
252*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invokeExact("target", 42l, 56);
253*795d594fSAndroid Build Coastguard Worker     assertEquals("target", returnVal);
254*795d594fSAndroid Build Coastguard Worker 
255*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invoke("fallback", 42l, 56);
256*795d594fSAndroid Build Coastguard Worker     assertEquals("fallback", returnVal);
257*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invokeExact("target", 42l, 56);
258*795d594fSAndroid Build Coastguard Worker     assertEquals("target", returnVal);
259*795d594fSAndroid Build Coastguard Worker 
260*795d594fSAndroid Build Coastguard Worker     // Check that asType works as expected.
261*795d594fSAndroid Build Coastguard Worker     adapter = adapter.asType(MethodType.methodType(String.class,
262*795d594fSAndroid Build Coastguard Worker           new Class<?>[] { String.class, int.class, int.class }));
263*795d594fSAndroid Build Coastguard Worker     returnVal = (String) adapter.invokeExact("target", 42, 56);
264*795d594fSAndroid Build Coastguard Worker     assertEquals("target", returnVal);
265*795d594fSAndroid Build Coastguard Worker   }
266*795d594fSAndroid Build Coastguard Worker 
testArrayElementGetter()267*795d594fSAndroid Build Coastguard Worker   public static void testArrayElementGetter() throws Throwable {
268*795d594fSAndroid Build Coastguard Worker     MethodHandle getter = MethodHandles.arrayElementGetter(int[].class);
269*795d594fSAndroid Build Coastguard Worker 
270*795d594fSAndroid Build Coastguard Worker     {
271*795d594fSAndroid Build Coastguard Worker       int[] array = new int[1];
272*795d594fSAndroid Build Coastguard Worker       array[0] = 42;
273*795d594fSAndroid Build Coastguard Worker       int value = (int) getter.invoke(array, 0);
274*795d594fSAndroid Build Coastguard Worker       if (value != 42) {
275*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
276*795d594fSAndroid Build Coastguard Worker       }
277*795d594fSAndroid Build Coastguard Worker 
278*795d594fSAndroid Build Coastguard Worker       try {
279*795d594fSAndroid Build Coastguard Worker         value = (int) getter.invoke(array, -1);
280*795d594fSAndroid Build Coastguard Worker         fail();
281*795d594fSAndroid Build Coastguard Worker       } catch (ArrayIndexOutOfBoundsException expected) {
282*795d594fSAndroid Build Coastguard Worker       }
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker       try {
285*795d594fSAndroid Build Coastguard Worker         value = (int) getter.invoke(null, -1);
286*795d594fSAndroid Build Coastguard Worker         fail();
287*795d594fSAndroid Build Coastguard Worker       } catch (NullPointerException expected) {
288*795d594fSAndroid Build Coastguard Worker       }
289*795d594fSAndroid Build Coastguard Worker     }
290*795d594fSAndroid Build Coastguard Worker 
291*795d594fSAndroid Build Coastguard Worker     {
292*795d594fSAndroid Build Coastguard Worker       getter = MethodHandles.arrayElementGetter(long[].class);
293*795d594fSAndroid Build Coastguard Worker       long[] array = new long[1];
294*795d594fSAndroid Build Coastguard Worker       array[0] = 42;
295*795d594fSAndroid Build Coastguard Worker       long value = (long) getter.invoke(array, 0);
296*795d594fSAndroid Build Coastguard Worker       if (value != 42l) {
297*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
298*795d594fSAndroid Build Coastguard Worker       }
299*795d594fSAndroid Build Coastguard Worker     }
300*795d594fSAndroid Build Coastguard Worker 
301*795d594fSAndroid Build Coastguard Worker     {
302*795d594fSAndroid Build Coastguard Worker       getter = MethodHandles.arrayElementGetter(short[].class);
303*795d594fSAndroid Build Coastguard Worker       short[] array = new short[1];
304*795d594fSAndroid Build Coastguard Worker       array[0] = 42;
305*795d594fSAndroid Build Coastguard Worker       short value = (short) getter.invoke(array, 0);
306*795d594fSAndroid Build Coastguard Worker       if (value != 42l) {
307*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
308*795d594fSAndroid Build Coastguard Worker       }
309*795d594fSAndroid Build Coastguard Worker     }
310*795d594fSAndroid Build Coastguard Worker 
311*795d594fSAndroid Build Coastguard Worker     {
312*795d594fSAndroid Build Coastguard Worker       getter = MethodHandles.arrayElementGetter(char[].class);
313*795d594fSAndroid Build Coastguard Worker       char[] array = new char[1];
314*795d594fSAndroid Build Coastguard Worker       array[0] = 42;
315*795d594fSAndroid Build Coastguard Worker       char value = (char) getter.invoke(array, 0);
316*795d594fSAndroid Build Coastguard Worker       if (value != 42l) {
317*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
318*795d594fSAndroid Build Coastguard Worker       }
319*795d594fSAndroid Build Coastguard Worker     }
320*795d594fSAndroid Build Coastguard Worker 
321*795d594fSAndroid Build Coastguard Worker     {
322*795d594fSAndroid Build Coastguard Worker       getter = MethodHandles.arrayElementGetter(byte[].class);
323*795d594fSAndroid Build Coastguard Worker       byte[] array = new byte[1];
324*795d594fSAndroid Build Coastguard Worker       array[0] = (byte) 0x8;
325*795d594fSAndroid Build Coastguard Worker       byte value = (byte) getter.invoke(array, 0);
326*795d594fSAndroid Build Coastguard Worker       if (value != (byte) 0x8) {
327*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
328*795d594fSAndroid Build Coastguard Worker       }
329*795d594fSAndroid Build Coastguard Worker     }
330*795d594fSAndroid Build Coastguard Worker 
331*795d594fSAndroid Build Coastguard Worker     {
332*795d594fSAndroid Build Coastguard Worker       getter = MethodHandles.arrayElementGetter(boolean[].class);
333*795d594fSAndroid Build Coastguard Worker       boolean[] array = new boolean[1];
334*795d594fSAndroid Build Coastguard Worker       array[0] = true;
335*795d594fSAndroid Build Coastguard Worker       boolean value = (boolean) getter.invoke(array, 0);
336*795d594fSAndroid Build Coastguard Worker       if (!value) {
337*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
338*795d594fSAndroid Build Coastguard Worker       }
339*795d594fSAndroid Build Coastguard Worker     }
340*795d594fSAndroid Build Coastguard Worker 
341*795d594fSAndroid Build Coastguard Worker     {
342*795d594fSAndroid Build Coastguard Worker       getter = MethodHandles.arrayElementGetter(float[].class);
343*795d594fSAndroid Build Coastguard Worker       float[] array = new float[1];
344*795d594fSAndroid Build Coastguard Worker       array[0] = 42.0f;
345*795d594fSAndroid Build Coastguard Worker       float value = (float) getter.invoke(array, 0);
346*795d594fSAndroid Build Coastguard Worker       if (value != 42.0f) {
347*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
348*795d594fSAndroid Build Coastguard Worker       }
349*795d594fSAndroid Build Coastguard Worker     }
350*795d594fSAndroid Build Coastguard Worker 
351*795d594fSAndroid Build Coastguard Worker     {
352*795d594fSAndroid Build Coastguard Worker       getter = MethodHandles.arrayElementGetter(double[].class);
353*795d594fSAndroid Build Coastguard Worker       double[] array = new double[1];
354*795d594fSAndroid Build Coastguard Worker       array[0] = 42.0;
355*795d594fSAndroid Build Coastguard Worker       double value = (double) getter.invoke(array, 0);
356*795d594fSAndroid Build Coastguard Worker       if (value != 42.0) {
357*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
358*795d594fSAndroid Build Coastguard Worker       }
359*795d594fSAndroid Build Coastguard Worker     }
360*795d594fSAndroid Build Coastguard Worker 
361*795d594fSAndroid Build Coastguard Worker     {
362*795d594fSAndroid Build Coastguard Worker       getter = MethodHandles.arrayElementGetter(String[].class);
363*795d594fSAndroid Build Coastguard Worker       String[] array = new String[3];
364*795d594fSAndroid Build Coastguard Worker       array[0] = "42";
365*795d594fSAndroid Build Coastguard Worker       array[1] = "48";
366*795d594fSAndroid Build Coastguard Worker       array[2] = "54";
367*795d594fSAndroid Build Coastguard Worker       String value = (String) getter.invoke(array, 0);
368*795d594fSAndroid Build Coastguard Worker       assertEquals("42", value);
369*795d594fSAndroid Build Coastguard Worker       value = (String) getter.invoke(array, 1);
370*795d594fSAndroid Build Coastguard Worker       assertEquals("48", value);
371*795d594fSAndroid Build Coastguard Worker       value = (String) getter.invoke(array, 2);
372*795d594fSAndroid Build Coastguard Worker       assertEquals("54", value);
373*795d594fSAndroid Build Coastguard Worker     }
374*795d594fSAndroid Build Coastguard Worker   }
375*795d594fSAndroid Build Coastguard Worker 
testArrayElementSetter()376*795d594fSAndroid Build Coastguard Worker   public static void testArrayElementSetter() throws Throwable {
377*795d594fSAndroid Build Coastguard Worker     MethodHandle setter = MethodHandles.arrayElementSetter(int[].class);
378*795d594fSAndroid Build Coastguard Worker 
379*795d594fSAndroid Build Coastguard Worker     {
380*795d594fSAndroid Build Coastguard Worker       int[] array = new int[2];
381*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 0, 42);
382*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 1, 43);
383*795d594fSAndroid Build Coastguard Worker 
384*795d594fSAndroid Build Coastguard Worker       if (array[0] != 42) {
385*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + array[0]);
386*795d594fSAndroid Build Coastguard Worker       }
387*795d594fSAndroid Build Coastguard Worker       if (array[1] != 43) {
388*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + array[1]);
389*795d594fSAndroid Build Coastguard Worker       }
390*795d594fSAndroid Build Coastguard Worker 
391*795d594fSAndroid Build Coastguard Worker       try {
392*795d594fSAndroid Build Coastguard Worker         setter.invoke(array, -1, 42);
393*795d594fSAndroid Build Coastguard Worker         fail();
394*795d594fSAndroid Build Coastguard Worker       } catch (ArrayIndexOutOfBoundsException expected) {
395*795d594fSAndroid Build Coastguard Worker       }
396*795d594fSAndroid Build Coastguard Worker 
397*795d594fSAndroid Build Coastguard Worker       try {
398*795d594fSAndroid Build Coastguard Worker         setter.invoke(null, 0, 42);
399*795d594fSAndroid Build Coastguard Worker         fail();
400*795d594fSAndroid Build Coastguard Worker       } catch (NullPointerException expected) {
401*795d594fSAndroid Build Coastguard Worker       }
402*795d594fSAndroid Build Coastguard Worker     }
403*795d594fSAndroid Build Coastguard Worker 
404*795d594fSAndroid Build Coastguard Worker     {
405*795d594fSAndroid Build Coastguard Worker       setter = MethodHandles.arrayElementSetter(long[].class);
406*795d594fSAndroid Build Coastguard Worker       long[] array = new long[1];
407*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 0, 42l);
408*795d594fSAndroid Build Coastguard Worker       if (array[0] != 42l) {
409*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + array[0]);
410*795d594fSAndroid Build Coastguard Worker       }
411*795d594fSAndroid Build Coastguard Worker     }
412*795d594fSAndroid Build Coastguard Worker 
413*795d594fSAndroid Build Coastguard Worker     {
414*795d594fSAndroid Build Coastguard Worker       setter = MethodHandles.arrayElementSetter(short[].class);
415*795d594fSAndroid Build Coastguard Worker       short[] array = new short[1];
416*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 0, (short) 42);
417*795d594fSAndroid Build Coastguard Worker       if (array[0] != 42l) {
418*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + array[0]);
419*795d594fSAndroid Build Coastguard Worker       }
420*795d594fSAndroid Build Coastguard Worker     }
421*795d594fSAndroid Build Coastguard Worker 
422*795d594fSAndroid Build Coastguard Worker     {
423*795d594fSAndroid Build Coastguard Worker       setter = MethodHandles.arrayElementSetter(char[].class);
424*795d594fSAndroid Build Coastguard Worker       char[] array = new char[1];
425*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 0, (char) 42);
426*795d594fSAndroid Build Coastguard Worker       if (array[0] != 42) {
427*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + array[0]);
428*795d594fSAndroid Build Coastguard Worker       }
429*795d594fSAndroid Build Coastguard Worker     }
430*795d594fSAndroid Build Coastguard Worker 
431*795d594fSAndroid Build Coastguard Worker     {
432*795d594fSAndroid Build Coastguard Worker       setter = MethodHandles.arrayElementSetter(byte[].class);
433*795d594fSAndroid Build Coastguard Worker       byte[] array = new byte[1];
434*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 0, (byte) 0x8);
435*795d594fSAndroid Build Coastguard Worker       if (array[0] != (byte) 0x8) {
436*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + array[0]);
437*795d594fSAndroid Build Coastguard Worker       }
438*795d594fSAndroid Build Coastguard Worker     }
439*795d594fSAndroid Build Coastguard Worker 
440*795d594fSAndroid Build Coastguard Worker     {
441*795d594fSAndroid Build Coastguard Worker       setter = MethodHandles.arrayElementSetter(boolean[].class);
442*795d594fSAndroid Build Coastguard Worker       boolean[] array = new boolean[1];
443*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 0, true);
444*795d594fSAndroid Build Coastguard Worker       if (!array[0]) {
445*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + array[0]);
446*795d594fSAndroid Build Coastguard Worker       }
447*795d594fSAndroid Build Coastguard Worker     }
448*795d594fSAndroid Build Coastguard Worker 
449*795d594fSAndroid Build Coastguard Worker     {
450*795d594fSAndroid Build Coastguard Worker       setter = MethodHandles.arrayElementSetter(float[].class);
451*795d594fSAndroid Build Coastguard Worker       float[] array = new float[1];
452*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 0, 42.0f);
453*795d594fSAndroid Build Coastguard Worker       if (array[0] != 42.0f) {
454*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + array[0]);
455*795d594fSAndroid Build Coastguard Worker       }
456*795d594fSAndroid Build Coastguard Worker     }
457*795d594fSAndroid Build Coastguard Worker 
458*795d594fSAndroid Build Coastguard Worker     {
459*795d594fSAndroid Build Coastguard Worker       setter = MethodHandles.arrayElementSetter(double[].class);
460*795d594fSAndroid Build Coastguard Worker       double[] array = new double[1];
461*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 0, 42.0);
462*795d594fSAndroid Build Coastguard Worker       if (array[0] != 42.0) {
463*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + array[0]);
464*795d594fSAndroid Build Coastguard Worker       }
465*795d594fSAndroid Build Coastguard Worker     }
466*795d594fSAndroid Build Coastguard Worker 
467*795d594fSAndroid Build Coastguard Worker     {
468*795d594fSAndroid Build Coastguard Worker       setter = MethodHandles.arrayElementSetter(String[].class);
469*795d594fSAndroid Build Coastguard Worker       String[] array = new String[3];
470*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 0, "42");
471*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 1, "48");
472*795d594fSAndroid Build Coastguard Worker       setter.invoke(array, 2, "54");
473*795d594fSAndroid Build Coastguard Worker       assertEquals("42", array[0]);
474*795d594fSAndroid Build Coastguard Worker       assertEquals("48", array[1]);
475*795d594fSAndroid Build Coastguard Worker       assertEquals("54", array[2]);
476*795d594fSAndroid Build Coastguard Worker     }
477*795d594fSAndroid Build Coastguard Worker   }
478*795d594fSAndroid Build Coastguard Worker 
testIdentity()479*795d594fSAndroid Build Coastguard Worker   public static void testIdentity() throws Throwable {
480*795d594fSAndroid Build Coastguard Worker     {
481*795d594fSAndroid Build Coastguard Worker       MethodHandle identity = MethodHandles.identity(boolean.class);
482*795d594fSAndroid Build Coastguard Worker       boolean value = (boolean) identity.invoke(false);
483*795d594fSAndroid Build Coastguard Worker       if (value) {
484*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
485*795d594fSAndroid Build Coastguard Worker       }
486*795d594fSAndroid Build Coastguard Worker     }
487*795d594fSAndroid Build Coastguard Worker 
488*795d594fSAndroid Build Coastguard Worker     {
489*795d594fSAndroid Build Coastguard Worker       MethodHandle identity = MethodHandles.identity(byte.class);
490*795d594fSAndroid Build Coastguard Worker       byte value = (byte) identity.invoke((byte) 0x8);
491*795d594fSAndroid Build Coastguard Worker       if (value != (byte) 0x8) {
492*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
493*795d594fSAndroid Build Coastguard Worker       }
494*795d594fSAndroid Build Coastguard Worker     }
495*795d594fSAndroid Build Coastguard Worker 
496*795d594fSAndroid Build Coastguard Worker     {
497*795d594fSAndroid Build Coastguard Worker       MethodHandle identity = MethodHandles.identity(char.class);
498*795d594fSAndroid Build Coastguard Worker       char value = (char) identity.invoke((char) -56);
499*795d594fSAndroid Build Coastguard Worker       if (value != (char) -56) {
500*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
501*795d594fSAndroid Build Coastguard Worker       }
502*795d594fSAndroid Build Coastguard Worker     }
503*795d594fSAndroid Build Coastguard Worker 
504*795d594fSAndroid Build Coastguard Worker     {
505*795d594fSAndroid Build Coastguard Worker       MethodHandle identity = MethodHandles.identity(short.class);
506*795d594fSAndroid Build Coastguard Worker       short value = (short) identity.invoke((short) -59);
507*795d594fSAndroid Build Coastguard Worker       if (value != (short) -59) {
508*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + Short.toString(value));
509*795d594fSAndroid Build Coastguard Worker       }
510*795d594fSAndroid Build Coastguard Worker     }
511*795d594fSAndroid Build Coastguard Worker 
512*795d594fSAndroid Build Coastguard Worker     {
513*795d594fSAndroid Build Coastguard Worker       MethodHandle identity = MethodHandles.identity(int.class);
514*795d594fSAndroid Build Coastguard Worker       int value = (int) identity.invoke(52);
515*795d594fSAndroid Build Coastguard Worker       if (value != 52) {
516*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
517*795d594fSAndroid Build Coastguard Worker       }
518*795d594fSAndroid Build Coastguard Worker     }
519*795d594fSAndroid Build Coastguard Worker 
520*795d594fSAndroid Build Coastguard Worker     {
521*795d594fSAndroid Build Coastguard Worker       MethodHandle identity = MethodHandles.identity(long.class);
522*795d594fSAndroid Build Coastguard Worker       long value = (long) identity.invoke(-76l);
523*795d594fSAndroid Build Coastguard Worker       if (value != (long) -76) {
524*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
525*795d594fSAndroid Build Coastguard Worker       }
526*795d594fSAndroid Build Coastguard Worker     }
527*795d594fSAndroid Build Coastguard Worker 
528*795d594fSAndroid Build Coastguard Worker     {
529*795d594fSAndroid Build Coastguard Worker       MethodHandle identity = MethodHandles.identity(float.class);
530*795d594fSAndroid Build Coastguard Worker       float value = (float) identity.invoke(56.0f);
531*795d594fSAndroid Build Coastguard Worker       if (value != (float) 56.0f) {
532*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
533*795d594fSAndroid Build Coastguard Worker       }
534*795d594fSAndroid Build Coastguard Worker     }
535*795d594fSAndroid Build Coastguard Worker 
536*795d594fSAndroid Build Coastguard Worker     {
537*795d594fSAndroid Build Coastguard Worker       MethodHandle identity = MethodHandles.identity(double.class);
538*795d594fSAndroid Build Coastguard Worker       double value = (double) identity.invoke((double) 72.0);
539*795d594fSAndroid Build Coastguard Worker       if (value != (double) 72.0) {
540*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
541*795d594fSAndroid Build Coastguard Worker       }
542*795d594fSAndroid Build Coastguard Worker     }
543*795d594fSAndroid Build Coastguard Worker 
544*795d594fSAndroid Build Coastguard Worker     {
545*795d594fSAndroid Build Coastguard Worker       MethodHandle identity = MethodHandles.identity(String.class);
546*795d594fSAndroid Build Coastguard Worker       String value = (String) identity.invoke("bazman");
547*795d594fSAndroid Build Coastguard Worker       assertEquals("bazman", value);
548*795d594fSAndroid Build Coastguard Worker     }
549*795d594fSAndroid Build Coastguard Worker   }
550*795d594fSAndroid Build Coastguard Worker 
testConstant()551*795d594fSAndroid Build Coastguard Worker   public static void testConstant() throws Throwable {
552*795d594fSAndroid Build Coastguard Worker     // int constants.
553*795d594fSAndroid Build Coastguard Worker     {
554*795d594fSAndroid Build Coastguard Worker       MethodHandle constant = MethodHandles.constant(int.class, 56);
555*795d594fSAndroid Build Coastguard Worker       int value = (int) constant.invoke();
556*795d594fSAndroid Build Coastguard Worker       if (value != 56) {
557*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
558*795d594fSAndroid Build Coastguard Worker       }
559*795d594fSAndroid Build Coastguard Worker 
560*795d594fSAndroid Build Coastguard Worker       // short constant values are converted to int.
561*795d594fSAndroid Build Coastguard Worker       constant = MethodHandles.constant(int.class, (short) 52);
562*795d594fSAndroid Build Coastguard Worker       value = (int) constant.invoke();
563*795d594fSAndroid Build Coastguard Worker       if (value != 52) {
564*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
565*795d594fSAndroid Build Coastguard Worker       }
566*795d594fSAndroid Build Coastguard Worker 
567*795d594fSAndroid Build Coastguard Worker       // char constant values are converted to int.
568*795d594fSAndroid Build Coastguard Worker       constant = MethodHandles.constant(int.class, (char) 'b');
569*795d594fSAndroid Build Coastguard Worker       value = (int) constant.invoke();
570*795d594fSAndroid Build Coastguard Worker       if (value != (int) 'b') {
571*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
572*795d594fSAndroid Build Coastguard Worker       }
573*795d594fSAndroid Build Coastguard Worker 
574*795d594fSAndroid Build Coastguard Worker       // int constant values are converted to int.
575*795d594fSAndroid Build Coastguard Worker       constant = MethodHandles.constant(int.class, (byte) 0x1);
576*795d594fSAndroid Build Coastguard Worker       value = (int) constant.invoke();
577*795d594fSAndroid Build Coastguard Worker       if (value != 1) {
578*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
579*795d594fSAndroid Build Coastguard Worker       }
580*795d594fSAndroid Build Coastguard Worker 
581*795d594fSAndroid Build Coastguard Worker       // boolean, float, double and long primitive constants are not convertible
582*795d594fSAndroid Build Coastguard Worker       // to int, so the handle creation must fail with a CCE.
583*795d594fSAndroid Build Coastguard Worker       try {
584*795d594fSAndroid Build Coastguard Worker         MethodHandles.constant(int.class, false);
585*795d594fSAndroid Build Coastguard Worker         fail();
586*795d594fSAndroid Build Coastguard Worker       } catch (ClassCastException expected) {
587*795d594fSAndroid Build Coastguard Worker       }
588*795d594fSAndroid Build Coastguard Worker 
589*795d594fSAndroid Build Coastguard Worker       try {
590*795d594fSAndroid Build Coastguard Worker         MethodHandles.constant(int.class, 0.1f);
591*795d594fSAndroid Build Coastguard Worker         fail();
592*795d594fSAndroid Build Coastguard Worker       } catch (ClassCastException expected) {
593*795d594fSAndroid Build Coastguard Worker       }
594*795d594fSAndroid Build Coastguard Worker 
595*795d594fSAndroid Build Coastguard Worker       try {
596*795d594fSAndroid Build Coastguard Worker         MethodHandles.constant(int.class, 0.2);
597*795d594fSAndroid Build Coastguard Worker         fail();
598*795d594fSAndroid Build Coastguard Worker       } catch (ClassCastException expected) {
599*795d594fSAndroid Build Coastguard Worker       }
600*795d594fSAndroid Build Coastguard Worker 
601*795d594fSAndroid Build Coastguard Worker       try {
602*795d594fSAndroid Build Coastguard Worker         MethodHandles.constant(int.class, 73l);
603*795d594fSAndroid Build Coastguard Worker         fail();
604*795d594fSAndroid Build Coastguard Worker       } catch (ClassCastException expected) {
605*795d594fSAndroid Build Coastguard Worker       }
606*795d594fSAndroid Build Coastguard Worker     }
607*795d594fSAndroid Build Coastguard Worker 
608*795d594fSAndroid Build Coastguard Worker     // long constants.
609*795d594fSAndroid Build Coastguard Worker     {
610*795d594fSAndroid Build Coastguard Worker       MethodHandle constant = MethodHandles.constant(long.class, 56l);
611*795d594fSAndroid Build Coastguard Worker       long value = (long) constant.invoke();
612*795d594fSAndroid Build Coastguard Worker       if (value != 56l) {
613*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
614*795d594fSAndroid Build Coastguard Worker       }
615*795d594fSAndroid Build Coastguard Worker 
616*795d594fSAndroid Build Coastguard Worker       constant = MethodHandles.constant(long.class, (int) 56);
617*795d594fSAndroid Build Coastguard Worker       value = (long) constant.invoke();
618*795d594fSAndroid Build Coastguard Worker       if (value != 56l) {
619*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
620*795d594fSAndroid Build Coastguard Worker       }
621*795d594fSAndroid Build Coastguard Worker     }
622*795d594fSAndroid Build Coastguard Worker 
623*795d594fSAndroid Build Coastguard Worker     // byte constants.
624*795d594fSAndroid Build Coastguard Worker     {
625*795d594fSAndroid Build Coastguard Worker       MethodHandle constant = MethodHandles.constant(byte.class, (byte) 0x12);
626*795d594fSAndroid Build Coastguard Worker       byte value = (byte) constant.invoke();
627*795d594fSAndroid Build Coastguard Worker       if (value != (byte) 0x12) {
628*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
629*795d594fSAndroid Build Coastguard Worker       }
630*795d594fSAndroid Build Coastguard Worker     }
631*795d594fSAndroid Build Coastguard Worker 
632*795d594fSAndroid Build Coastguard Worker     // boolean constants.
633*795d594fSAndroid Build Coastguard Worker     {
634*795d594fSAndroid Build Coastguard Worker       MethodHandle constant = MethodHandles.constant(boolean.class, true);
635*795d594fSAndroid Build Coastguard Worker       boolean value = (boolean) constant.invoke();
636*795d594fSAndroid Build Coastguard Worker       if (!value) {
637*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
638*795d594fSAndroid Build Coastguard Worker       }
639*795d594fSAndroid Build Coastguard Worker     }
640*795d594fSAndroid Build Coastguard Worker 
641*795d594fSAndroid Build Coastguard Worker     // char constants.
642*795d594fSAndroid Build Coastguard Worker     {
643*795d594fSAndroid Build Coastguard Worker       MethodHandle constant = MethodHandles.constant(char.class, 'f');
644*795d594fSAndroid Build Coastguard Worker       char value = (char) constant.invoke();
645*795d594fSAndroid Build Coastguard Worker       if (value != 'f') {
646*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
647*795d594fSAndroid Build Coastguard Worker       }
648*795d594fSAndroid Build Coastguard Worker     }
649*795d594fSAndroid Build Coastguard Worker 
650*795d594fSAndroid Build Coastguard Worker     // short constants.
651*795d594fSAndroid Build Coastguard Worker     {
652*795d594fSAndroid Build Coastguard Worker       MethodHandle constant = MethodHandles.constant(short.class, (short) 123);
653*795d594fSAndroid Build Coastguard Worker       short value = (short) constant.invoke();
654*795d594fSAndroid Build Coastguard Worker       if (value != (short) 123) {
655*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
656*795d594fSAndroid Build Coastguard Worker       }
657*795d594fSAndroid Build Coastguard Worker     }
658*795d594fSAndroid Build Coastguard Worker 
659*795d594fSAndroid Build Coastguard Worker     // float constants.
660*795d594fSAndroid Build Coastguard Worker     {
661*795d594fSAndroid Build Coastguard Worker       MethodHandle constant = MethodHandles.constant(float.class, 56.0f);
662*795d594fSAndroid Build Coastguard Worker       float value = (float) constant.invoke();
663*795d594fSAndroid Build Coastguard Worker       if (value != 56.0f) {
664*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
665*795d594fSAndroid Build Coastguard Worker       }
666*795d594fSAndroid Build Coastguard Worker     }
667*795d594fSAndroid Build Coastguard Worker 
668*795d594fSAndroid Build Coastguard Worker     // double constants.
669*795d594fSAndroid Build Coastguard Worker     {
670*795d594fSAndroid Build Coastguard Worker       MethodHandle constant = MethodHandles.constant(double.class, 256.0);
671*795d594fSAndroid Build Coastguard Worker       double value = (double) constant.invoke();
672*795d594fSAndroid Build Coastguard Worker       if (value != 256.0) {
673*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
674*795d594fSAndroid Build Coastguard Worker       }
675*795d594fSAndroid Build Coastguard Worker     }
676*795d594fSAndroid Build Coastguard Worker 
677*795d594fSAndroid Build Coastguard Worker     // reference constants.
678*795d594fSAndroid Build Coastguard Worker     {
679*795d594fSAndroid Build Coastguard Worker       MethodHandle constant = MethodHandles.constant(String.class, "256.0");
680*795d594fSAndroid Build Coastguard Worker       String value = (String) constant.invoke();
681*795d594fSAndroid Build Coastguard Worker       assertEquals("256.0", value);
682*795d594fSAndroid Build Coastguard Worker     }
683*795d594fSAndroid Build Coastguard Worker   }
684*795d594fSAndroid Build Coastguard Worker 
testBindTo()685*795d594fSAndroid Build Coastguard Worker   public static void testBindTo() throws Throwable {
686*795d594fSAndroid Build Coastguard Worker     MethodHandle stringCharAt = MethodHandles.lookup().findVirtual(
687*795d594fSAndroid Build Coastguard Worker         String.class, "charAt", MethodType.methodType(char.class, int.class));
688*795d594fSAndroid Build Coastguard Worker 
689*795d594fSAndroid Build Coastguard Worker     char value = (char) stringCharAt.invoke("foo", 0);
690*795d594fSAndroid Build Coastguard Worker     if (value != 'f') {
691*795d594fSAndroid Build Coastguard Worker       fail("Unexpected value: " + value);
692*795d594fSAndroid Build Coastguard Worker     }
693*795d594fSAndroid Build Coastguard Worker 
694*795d594fSAndroid Build Coastguard Worker     MethodHandle bound = stringCharAt.bindTo("foo");
695*795d594fSAndroid Build Coastguard Worker     value = (char) bound.invoke(0);
696*795d594fSAndroid Build Coastguard Worker     if (value != 'f') {
697*795d594fSAndroid Build Coastguard Worker       fail("Unexpected value: " + value);
698*795d594fSAndroid Build Coastguard Worker     }
699*795d594fSAndroid Build Coastguard Worker 
700*795d594fSAndroid Build Coastguard Worker     try {
701*795d594fSAndroid Build Coastguard Worker       stringCharAt.bindTo(new Object());
702*795d594fSAndroid Build Coastguard Worker       fail();
703*795d594fSAndroid Build Coastguard Worker     } catch (ClassCastException expected) {
704*795d594fSAndroid Build Coastguard Worker     }
705*795d594fSAndroid Build Coastguard Worker 
706*795d594fSAndroid Build Coastguard Worker     bound = stringCharAt.bindTo(null);
707*795d594fSAndroid Build Coastguard Worker     try {
708*795d594fSAndroid Build Coastguard Worker       bound.invoke(0);
709*795d594fSAndroid Build Coastguard Worker       fail();
710*795d594fSAndroid Build Coastguard Worker     } catch (NullPointerException expected) {
711*795d594fSAndroid Build Coastguard Worker     }
712*795d594fSAndroid Build Coastguard Worker 
713*795d594fSAndroid Build Coastguard Worker     MethodHandle integerParseInt = MethodHandles.lookup().findStatic(
714*795d594fSAndroid Build Coastguard Worker         Integer.class, "parseInt", MethodType.methodType(int.class, String.class));
715*795d594fSAndroid Build Coastguard Worker 
716*795d594fSAndroid Build Coastguard Worker     bound = integerParseInt.bindTo("78452");
717*795d594fSAndroid Build Coastguard Worker     int intValue = (int) bound.invoke();
718*795d594fSAndroid Build Coastguard Worker     if (intValue != 78452) {
719*795d594fSAndroid Build Coastguard Worker       fail("Unexpected value: " + intValue);
720*795d594fSAndroid Build Coastguard Worker     }
721*795d594fSAndroid Build Coastguard Worker 
722*795d594fSAndroid Build Coastguard Worker     class Locals {
723*795d594fSAndroid Build Coastguard Worker         public int intValue;
724*795d594fSAndroid Build Coastguard Worker     };
725*795d594fSAndroid Build Coastguard Worker 
726*795d594fSAndroid Build Coastguard Worker     MethodHandle setter1 = MethodHandles.lookup().findSetter(Locals.class, "intValue", int.class);
727*795d594fSAndroid Build Coastguard Worker     Locals locals = new Locals();
728*795d594fSAndroid Build Coastguard Worker     setter1.invoke(locals, 1);
729*795d594fSAndroid Build Coastguard Worker     assertEquals(1, locals.intValue);
730*795d594fSAndroid Build Coastguard Worker 
731*795d594fSAndroid Build Coastguard Worker     MethodHandle setter2 =
732*795d594fSAndroid Build Coastguard Worker         MethodHandles.insertArguments(setter1.bindTo(locals), 0, Integer.valueOf(2));
733*795d594fSAndroid Build Coastguard Worker     setter2.invoke();
734*795d594fSAndroid Build Coastguard Worker     assertEquals(2, locals.intValue);
735*795d594fSAndroid Build Coastguard Worker 
736*795d594fSAndroid Build Coastguard Worker     VarHandle vh = MethodHandles.lookup().findVarHandle(Locals.class,  "intValue", int.class);
737*795d594fSAndroid Build Coastguard Worker     MethodHandle setter3 = vh.toMethodHandle(VarHandle.AccessMode.GET_AND_SET);
738*795d594fSAndroid Build Coastguard Worker     assertEquals(setter3.type().toString(),
739*795d594fSAndroid Build Coastguard Worker                  MethodType.methodType(int.class, Locals.class, int.class).toString());
740*795d594fSAndroid Build Coastguard Worker     assertEquals(2, (int) setter3.invoke(locals, 3));
741*795d594fSAndroid Build Coastguard Worker 
742*795d594fSAndroid Build Coastguard Worker     MethodHandle setter4 =
743*795d594fSAndroid Build Coastguard Worker         MethodHandles.varHandleInvoker(VarHandle.AccessMode.GET_AND_SET,
744*795d594fSAndroid Build Coastguard Worker                                        MethodType.methodType(int.class, Locals.class, int.class));
745*795d594fSAndroid Build Coastguard Worker     assertEquals(3, (int) setter4.invoke(vh, locals, 4));
746*795d594fSAndroid Build Coastguard Worker 
747*795d594fSAndroid Build Coastguard Worker     MethodHandle setter5 = setter4.bindTo(vh);
748*795d594fSAndroid Build Coastguard Worker     assertEquals(4, (int) setter5.invoke(locals, 5));
749*795d594fSAndroid Build Coastguard Worker 
750*795d594fSAndroid Build Coastguard Worker     MethodHandle setter6 = MethodHandles.insertArguments(setter5, 0, locals, 6);
751*795d594fSAndroid Build Coastguard Worker     assertEquals(5, (int) setter6.invoke());
752*795d594fSAndroid Build Coastguard Worker     assertEquals(locals.intValue, 6);
753*795d594fSAndroid Build Coastguard Worker   }
754*795d594fSAndroid Build Coastguard Worker 
filterReturnValue_target(int a)755*795d594fSAndroid Build Coastguard Worker   public static String filterReturnValue_target(int a) {
756*795d594fSAndroid Build Coastguard Worker     return "ReturnValue" + a;
757*795d594fSAndroid Build Coastguard Worker   }
758*795d594fSAndroid Build Coastguard Worker 
filterReturnValue_filter(String value)759*795d594fSAndroid Build Coastguard Worker   public static boolean filterReturnValue_filter(String value) {
760*795d594fSAndroid Build Coastguard Worker     return value.indexOf("42") != -1;
761*795d594fSAndroid Build Coastguard Worker   }
762*795d594fSAndroid Build Coastguard Worker 
filterReturnValue_intTarget(String a)763*795d594fSAndroid Build Coastguard Worker   public static int filterReturnValue_intTarget(String a) {
764*795d594fSAndroid Build Coastguard Worker     return Integer.parseInt(a);
765*795d594fSAndroid Build Coastguard Worker   }
766*795d594fSAndroid Build Coastguard Worker 
filterReturnValue_intFilter(int b)767*795d594fSAndroid Build Coastguard Worker   public static int filterReturnValue_intFilter(int b) {
768*795d594fSAndroid Build Coastguard Worker     return b + 1;
769*795d594fSAndroid Build Coastguard Worker   }
770*795d594fSAndroid Build Coastguard Worker 
filterReturnValue_voidTarget()771*795d594fSAndroid Build Coastguard Worker   public static void filterReturnValue_voidTarget() {
772*795d594fSAndroid Build Coastguard Worker   }
773*795d594fSAndroid Build Coastguard Worker 
filterReturnValue_voidFilter()774*795d594fSAndroid Build Coastguard Worker   public static int filterReturnValue_voidFilter() {
775*795d594fSAndroid Build Coastguard Worker     return 42;
776*795d594fSAndroid Build Coastguard Worker   }
777*795d594fSAndroid Build Coastguard Worker 
testFilterReturnValue()778*795d594fSAndroid Build Coastguard Worker   public static void testFilterReturnValue() throws Throwable {
779*795d594fSAndroid Build Coastguard Worker     // A target that returns a reference.
780*795d594fSAndroid Build Coastguard Worker     {
781*795d594fSAndroid Build Coastguard Worker       final MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
782*795d594fSAndroid Build Coastguard Worker           "filterReturnValue_target", MethodType.methodType(String.class, int.class));
783*795d594fSAndroid Build Coastguard Worker       final MethodHandle filter = MethodHandles.lookup().findStatic(Main.class,
784*795d594fSAndroid Build Coastguard Worker           "filterReturnValue_filter", MethodType.methodType(boolean.class, String.class));
785*795d594fSAndroid Build Coastguard Worker 
786*795d594fSAndroid Build Coastguard Worker       MethodHandle adapter = MethodHandles.filterReturnValue(target, filter);
787*795d594fSAndroid Build Coastguard Worker 
788*795d594fSAndroid Build Coastguard Worker       boolean value = (boolean) adapter.invoke((int) 42);
789*795d594fSAndroid Build Coastguard Worker       if (!value) {
790*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
791*795d594fSAndroid Build Coastguard Worker       }
792*795d594fSAndroid Build Coastguard Worker       value = (boolean) adapter.invoke((int) 43);
793*795d594fSAndroid Build Coastguard Worker       if (value) {
794*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
795*795d594fSAndroid Build Coastguard Worker       }
796*795d594fSAndroid Build Coastguard Worker     }
797*795d594fSAndroid Build Coastguard Worker 
798*795d594fSAndroid Build Coastguard Worker     // A target that returns a primitive.
799*795d594fSAndroid Build Coastguard Worker     {
800*795d594fSAndroid Build Coastguard Worker       final MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
801*795d594fSAndroid Build Coastguard Worker           "filterReturnValue_intTarget", MethodType.methodType(int.class, String.class));
802*795d594fSAndroid Build Coastguard Worker       final MethodHandle filter = MethodHandles.lookup().findStatic(Main.class,
803*795d594fSAndroid Build Coastguard Worker           "filterReturnValue_intFilter", MethodType.methodType(int.class, int.class));
804*795d594fSAndroid Build Coastguard Worker 
805*795d594fSAndroid Build Coastguard Worker       MethodHandle adapter = MethodHandles.filterReturnValue(target, filter);
806*795d594fSAndroid Build Coastguard Worker 
807*795d594fSAndroid Build Coastguard Worker       int value = (int) adapter.invoke("56");
808*795d594fSAndroid Build Coastguard Worker       if (value != 57) {
809*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
810*795d594fSAndroid Build Coastguard Worker       }
811*795d594fSAndroid Build Coastguard Worker     }
812*795d594fSAndroid Build Coastguard Worker 
813*795d594fSAndroid Build Coastguard Worker     // A target that returns void.
814*795d594fSAndroid Build Coastguard Worker     {
815*795d594fSAndroid Build Coastguard Worker       final MethodHandle target = MethodHandles.lookup().findStatic(Main.class,
816*795d594fSAndroid Build Coastguard Worker           "filterReturnValue_voidTarget", MethodType.methodType(void.class));
817*795d594fSAndroid Build Coastguard Worker       final MethodHandle filter = MethodHandles.lookup().findStatic(Main.class,
818*795d594fSAndroid Build Coastguard Worker           "filterReturnValue_voidFilter", MethodType.methodType(int.class));
819*795d594fSAndroid Build Coastguard Worker 
820*795d594fSAndroid Build Coastguard Worker       MethodHandle adapter = MethodHandles.filterReturnValue(target, filter);
821*795d594fSAndroid Build Coastguard Worker 
822*795d594fSAndroid Build Coastguard Worker       int value = (int) adapter.invoke();
823*795d594fSAndroid Build Coastguard Worker       if (value != 42) {
824*795d594fSAndroid Build Coastguard Worker         fail("Unexpected value: " + value);
825*795d594fSAndroid Build Coastguard Worker       }
826*795d594fSAndroid Build Coastguard Worker     }
827*795d594fSAndroid Build Coastguard Worker   }
828*795d594fSAndroid Build Coastguard Worker 
permuteArguments_callee(boolean a, byte b, char c, short d, int e, long f, float g, double h)829*795d594fSAndroid Build Coastguard Worker   public static void permuteArguments_callee(boolean a, byte b, char c,
830*795d594fSAndroid Build Coastguard Worker       short d, int e, long f, float g, double h) {
831*795d594fSAndroid Build Coastguard Worker     if (a == true && b == (byte) 'b' && c == 'c' && d == (short) 56 &&
832*795d594fSAndroid Build Coastguard Worker         e == 78 && f == (long) 97 && g == 98.0f && f == 97.0) {
833*795d594fSAndroid Build Coastguard Worker       return;
834*795d594fSAndroid Build Coastguard Worker     }
835*795d594fSAndroid Build Coastguard Worker 
836*795d594fSAndroid Build Coastguard Worker     fail("Unexpected arguments: " + a + ", " + b + ", " + c
837*795d594fSAndroid Build Coastguard Worker         + ", " + d + ", " + e + ", " + f + ", " + g + ", " + h);
838*795d594fSAndroid Build Coastguard Worker   }
839*795d594fSAndroid Build Coastguard Worker 
permuteArguments_boxingCallee(boolean a, Integer b)840*795d594fSAndroid Build Coastguard Worker   public static void permuteArguments_boxingCallee(boolean a, Integer b) {
841*795d594fSAndroid Build Coastguard Worker     if (a && b.intValue() == 42) {
842*795d594fSAndroid Build Coastguard Worker       return;
843*795d594fSAndroid Build Coastguard Worker     }
844*795d594fSAndroid Build Coastguard Worker 
845*795d594fSAndroid Build Coastguard Worker     fail("Unexpected arguments: " + a + ", " + b);
846*795d594fSAndroid Build Coastguard Worker   }
847*795d594fSAndroid Build Coastguard Worker 
testPermuteArguments()848*795d594fSAndroid Build Coastguard Worker   public static void testPermuteArguments() throws Throwable {
849*795d594fSAndroid Build Coastguard Worker     {
850*795d594fSAndroid Build Coastguard Worker       final MethodHandle target = MethodHandles.lookup().findStatic(
851*795d594fSAndroid Build Coastguard Worker           Main.class, "permuteArguments_callee",
852*795d594fSAndroid Build Coastguard Worker           MethodType.methodType(void.class, new Class<?>[] {
853*795d594fSAndroid Build Coastguard Worker             boolean.class, byte.class, char.class, short.class, int.class,
854*795d594fSAndroid Build Coastguard Worker             long.class, float.class, double.class }));
855*795d594fSAndroid Build Coastguard Worker 
856*795d594fSAndroid Build Coastguard Worker       final MethodType newType = MethodType.methodType(void.class, new Class<?>[] {
857*795d594fSAndroid Build Coastguard Worker         double.class, float.class, long.class, int.class, short.class, char.class,
858*795d594fSAndroid Build Coastguard Worker         byte.class, boolean.class });
859*795d594fSAndroid Build Coastguard Worker 
860*795d594fSAndroid Build Coastguard Worker       final MethodHandle permutation = MethodHandles.permuteArguments(
861*795d594fSAndroid Build Coastguard Worker           target, newType, new int[] { 7, 6, 5, 4, 3, 2, 1, 0 });
862*795d594fSAndroid Build Coastguard Worker 
863*795d594fSAndroid Build Coastguard Worker       permutation.invoke((double) 97.0, (float) 98.0f, (long) 97, 78,
864*795d594fSAndroid Build Coastguard Worker           (short) 56, 'c', (byte) 'b', (boolean) true);
865*795d594fSAndroid Build Coastguard Worker 
866*795d594fSAndroid Build Coastguard Worker       // The permutation array was not of the right length.
867*795d594fSAndroid Build Coastguard Worker       try {
868*795d594fSAndroid Build Coastguard Worker         MethodHandles.permuteArguments(target, newType,
869*795d594fSAndroid Build Coastguard Worker             new int[] { 7 });
870*795d594fSAndroid Build Coastguard Worker         fail();
871*795d594fSAndroid Build Coastguard Worker       } catch (IllegalArgumentException expected) {
872*795d594fSAndroid Build Coastguard Worker       }
873*795d594fSAndroid Build Coastguard Worker 
874*795d594fSAndroid Build Coastguard Worker       // The permutation array has an element that's out of bounds
875*795d594fSAndroid Build Coastguard Worker       // (there's no argument with idx == 8).
876*795d594fSAndroid Build Coastguard Worker       try {
877*795d594fSAndroid Build Coastguard Worker         MethodHandles.permuteArguments(target, newType,
878*795d594fSAndroid Build Coastguard Worker             new int[] { 8, 6, 5, 4, 3, 2, 1, 0 });
879*795d594fSAndroid Build Coastguard Worker         fail();
880*795d594fSAndroid Build Coastguard Worker       } catch (IllegalArgumentException expected) {
881*795d594fSAndroid Build Coastguard Worker       }
882*795d594fSAndroid Build Coastguard Worker 
883*795d594fSAndroid Build Coastguard Worker       // The permutation array maps to an incorrect type.
884*795d594fSAndroid Build Coastguard Worker       try {
885*795d594fSAndroid Build Coastguard Worker         MethodHandles.permuteArguments(target, newType,
886*795d594fSAndroid Build Coastguard Worker             new int[] { 7, 7, 5, 4, 3, 2, 1, 0 });
887*795d594fSAndroid Build Coastguard Worker         fail();
888*795d594fSAndroid Build Coastguard Worker       } catch (IllegalArgumentException expected) {
889*795d594fSAndroid Build Coastguard Worker       }
890*795d594fSAndroid Build Coastguard Worker     }
891*795d594fSAndroid Build Coastguard Worker 
892*795d594fSAndroid Build Coastguard Worker     // Tests for reference arguments as well as permutations that
893*795d594fSAndroid Build Coastguard Worker     // repeat arguments.
894*795d594fSAndroid Build Coastguard Worker     {
895*795d594fSAndroid Build Coastguard Worker       final MethodHandle target = MethodHandles.lookup().findVirtual(
896*795d594fSAndroid Build Coastguard Worker           String.class, "concat", MethodType.methodType(String.class, String.class));
897*795d594fSAndroid Build Coastguard Worker 
898*795d594fSAndroid Build Coastguard Worker       final MethodType newType = MethodType.methodType(String.class, String.class,
899*795d594fSAndroid Build Coastguard Worker           String.class);
900*795d594fSAndroid Build Coastguard Worker 
901*795d594fSAndroid Build Coastguard Worker       assertEquals("foobar", (String) target.invoke("foo", "bar"));
902*795d594fSAndroid Build Coastguard Worker 
903*795d594fSAndroid Build Coastguard Worker       MethodHandle permutation = MethodHandles.permuteArguments(target,
904*795d594fSAndroid Build Coastguard Worker           newType, new int[] { 1, 0 });
905*795d594fSAndroid Build Coastguard Worker       assertEquals("barfoo", (String) permutation.invoke("foo", "bar"));
906*795d594fSAndroid Build Coastguard Worker 
907*795d594fSAndroid Build Coastguard Worker       permutation = MethodHandles.permuteArguments(target, newType, new int[] { 0, 0 });
908*795d594fSAndroid Build Coastguard Worker       assertEquals("foofoo", (String) permutation.invoke("foo", "bar"));
909*795d594fSAndroid Build Coastguard Worker 
910*795d594fSAndroid Build Coastguard Worker       permutation = MethodHandles.permuteArguments(target, newType, new int[] { 1, 1 });
911*795d594fSAndroid Build Coastguard Worker       assertEquals("barbar", (String) permutation.invoke("foo", "bar"));
912*795d594fSAndroid Build Coastguard Worker     }
913*795d594fSAndroid Build Coastguard Worker 
914*795d594fSAndroid Build Coastguard Worker     // Tests for boxing and unboxing.
915*795d594fSAndroid Build Coastguard Worker     {
916*795d594fSAndroid Build Coastguard Worker       final MethodHandle target = MethodHandles.lookup().findStatic(
917*795d594fSAndroid Build Coastguard Worker           Main.class, "permuteArguments_boxingCallee",
918*795d594fSAndroid Build Coastguard Worker           MethodType.methodType(void.class, new Class<?>[] { boolean.class, Integer.class }));
919*795d594fSAndroid Build Coastguard Worker 
920*795d594fSAndroid Build Coastguard Worker       final MethodType newType = MethodType.methodType(void.class,
921*795d594fSAndroid Build Coastguard Worker           new Class<?>[] { Integer.class, boolean.class });
922*795d594fSAndroid Build Coastguard Worker 
923*795d594fSAndroid Build Coastguard Worker       MethodHandle permutation = MethodHandles.permuteArguments(target,
924*795d594fSAndroid Build Coastguard Worker           newType, new int[] { 1, 0 });
925*795d594fSAndroid Build Coastguard Worker 
926*795d594fSAndroid Build Coastguard Worker       permutation.invoke(42, true);
927*795d594fSAndroid Build Coastguard Worker       permutation.invoke(42, Boolean.TRUE);
928*795d594fSAndroid Build Coastguard Worker       permutation.invoke(Integer.valueOf(42), true);
929*795d594fSAndroid Build Coastguard Worker       permutation.invoke(Integer.valueOf(42), Boolean.TRUE);
930*795d594fSAndroid Build Coastguard Worker     }
931*795d594fSAndroid Build Coastguard Worker   }
932*795d594fSAndroid Build Coastguard Worker 
returnBar()933*795d594fSAndroid Build Coastguard Worker   private static Object returnBar() {
934*795d594fSAndroid Build Coastguard Worker     return "bar";
935*795d594fSAndroid Build Coastguard Worker   }
936*795d594fSAndroid Build Coastguard Worker 
testInvokers()937*795d594fSAndroid Build Coastguard Worker   public static void testInvokers() throws Throwable {
938*795d594fSAndroid Build Coastguard Worker     final MethodType targetType = MethodType.methodType(String.class, String.class);
939*795d594fSAndroid Build Coastguard Worker     final MethodHandle target = MethodHandles.lookup().findVirtual(
940*795d594fSAndroid Build Coastguard Worker         String.class, "concat", targetType);
941*795d594fSAndroid Build Coastguard Worker 
942*795d594fSAndroid Build Coastguard Worker     MethodHandle invoker = MethodHandles.invoker(target.type());
943*795d594fSAndroid Build Coastguard Worker     assertEquals("barbar", (String) invoker.invoke(target, "bar", "bar"));
944*795d594fSAndroid Build Coastguard Worker     assertEquals("barbar", (String) invoker.invoke(target, (Object) returnBar(), "bar"));
945*795d594fSAndroid Build Coastguard Worker     try {
946*795d594fSAndroid Build Coastguard Worker       String foo = (String) invoker.invoke(target, "bar", "bar", 24);
947*795d594fSAndroid Build Coastguard Worker       fail();
948*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
949*795d594fSAndroid Build Coastguard Worker     }
950*795d594fSAndroid Build Coastguard Worker 
951*795d594fSAndroid Build Coastguard Worker     MethodHandle exactInvoker = MethodHandles.exactInvoker(target.type());
952*795d594fSAndroid Build Coastguard Worker     assertEquals("barbar", (String) exactInvoker.invoke(target, "bar", "bar"));
953*795d594fSAndroid Build Coastguard Worker     assertEquals("barbar", (String) exactInvoker.invoke(target, (Object) returnBar(), "bar"));
954*795d594fSAndroid Build Coastguard Worker     try {
955*795d594fSAndroid Build Coastguard Worker       assertEquals("barbar", (String) invoker.invoke(target, (Object) Integer.valueOf(7), "bar"));
956*795d594fSAndroid Build Coastguard Worker       fail();
957*795d594fSAndroid Build Coastguard Worker     } catch (ClassCastException expected) {
958*795d594fSAndroid Build Coastguard Worker     }
959*795d594fSAndroid Build Coastguard Worker     try {
960*795d594fSAndroid Build Coastguard Worker       assertEquals("barbar", (String) invoker.invoke(target, (Object) null, "bar"));
961*795d594fSAndroid Build Coastguard Worker       fail();
962*795d594fSAndroid Build Coastguard Worker     } catch (NullPointerException expected) {
963*795d594fSAndroid Build Coastguard Worker     }
964*795d594fSAndroid Build Coastguard Worker     exactInvoker.invoke(target, (Object) returnBar(), "bar");
965*795d594fSAndroid Build Coastguard Worker 
966*795d594fSAndroid Build Coastguard Worker     try {
967*795d594fSAndroid Build Coastguard Worker       String foo = (String) exactInvoker.invoke(target, "bar", "bar", 24);
968*795d594fSAndroid Build Coastguard Worker       fail();
969*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
970*795d594fSAndroid Build Coastguard Worker     }
971*795d594fSAndroid Build Coastguard Worker   }
972*795d594fSAndroid Build Coastguard Worker 
spreadReferences(String a, String b, String c)973*795d594fSAndroid Build Coastguard Worker   public static int spreadReferences(String a, String b, String c) {
974*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c: " + c);
975*795d594fSAndroid Build Coastguard Worker     return 42;
976*795d594fSAndroid Build Coastguard Worker   }
977*795d594fSAndroid Build Coastguard Worker 
spreadReferences_Unbox(String a, int b)978*795d594fSAndroid Build Coastguard Worker   public static int spreadReferences_Unbox(String a, int b) {
979*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b);
980*795d594fSAndroid Build Coastguard Worker     return 43;
981*795d594fSAndroid Build Coastguard Worker   }
982*795d594fSAndroid Build Coastguard Worker 
testSpreaders_reference()983*795d594fSAndroid Build Coastguard Worker   public static void testSpreaders_reference() throws Throwable {
984*795d594fSAndroid Build Coastguard Worker     MethodType methodType = MethodType.methodType(int.class,
985*795d594fSAndroid Build Coastguard Worker         new Class<?>[] { String.class, String.class, String.class });
986*795d594fSAndroid Build Coastguard Worker     MethodHandle delegate = MethodHandles.lookup().findStatic(
987*795d594fSAndroid Build Coastguard Worker         Main.class, "spreadReferences", methodType);
988*795d594fSAndroid Build Coastguard Worker 
989*795d594fSAndroid Build Coastguard Worker     // Basic checks on array lengths.
990*795d594fSAndroid Build Coastguard Worker     //
991*795d594fSAndroid Build Coastguard Worker     // Array size = 0
992*795d594fSAndroid Build Coastguard Worker     MethodHandle mhAsSpreader = delegate.asSpreader(String[].class, 0);
993*795d594fSAndroid Build Coastguard Worker     int ret = (int) mhAsSpreader.invoke("a", "b", "c", new String[] {});
994*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
995*795d594fSAndroid Build Coastguard Worker     // Array size = 1
996*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate.asSpreader(String[].class, 1);
997*795d594fSAndroid Build Coastguard Worker     ret = (int) mhAsSpreader.invoke("a", "b", new String[] { "c" });
998*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
999*795d594fSAndroid Build Coastguard Worker     // Array size = 2
1000*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate.asSpreader(String[].class, 2);
1001*795d594fSAndroid Build Coastguard Worker     ret = (int) mhAsSpreader.invoke("a", new String[] { "b", "c" });
1002*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
1003*795d594fSAndroid Build Coastguard Worker     // Array size = 3
1004*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate.asSpreader(String[].class, 3);
1005*795d594fSAndroid Build Coastguard Worker     ret = (int) mhAsSpreader.invoke(new String[] { "a", "b", "c"});
1006*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
1007*795d594fSAndroid Build Coastguard Worker 
1008*795d594fSAndroid Build Coastguard Worker     // Exception case, array size = 4 is illegal.
1009*795d594fSAndroid Build Coastguard Worker     try {
1010*795d594fSAndroid Build Coastguard Worker       delegate.asSpreader(String[].class, 4);
1011*795d594fSAndroid Build Coastguard Worker       fail();
1012*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1013*795d594fSAndroid Build Coastguard Worker     }
1014*795d594fSAndroid Build Coastguard Worker 
1015*795d594fSAndroid Build Coastguard Worker     // Exception case, calling with an arg of the wrong size.
1016*795d594fSAndroid Build Coastguard Worker     // Array size = 3
1017*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate.asSpreader(String[].class, 3);
1018*795d594fSAndroid Build Coastguard Worker     try {
1019*795d594fSAndroid Build Coastguard Worker       ret = (int) mhAsSpreader.invoke(new String[] { "a", "b"});
1020*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1021*795d594fSAndroid Build Coastguard Worker     }
1022*795d594fSAndroid Build Coastguard Worker 
1023*795d594fSAndroid Build Coastguard Worker     // Various other hijinks, pass as Object[] arrays, Object etc.
1024*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate.asSpreader(Object[].class, 2);
1025*795d594fSAndroid Build Coastguard Worker     ret = (int) mhAsSpreader.invoke("a", new String[] { "b", "c" });
1026*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
1027*795d594fSAndroid Build Coastguard Worker 
1028*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate.asSpreader(Object[].class, 2);
1029*795d594fSAndroid Build Coastguard Worker     ret = (int) mhAsSpreader.invoke("a", new Object[] { "b", "c" });
1030*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
1031*795d594fSAndroid Build Coastguard Worker 
1032*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate.asSpreader(Object[].class, 2);
1033*795d594fSAndroid Build Coastguard Worker     ret = (int) mhAsSpreader.invoke("a", (Object) new Object[] { "b", "c" });
1034*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
1035*795d594fSAndroid Build Coastguard Worker 
1036*795d594fSAndroid Build Coastguard Worker     // Test implicit unboxing.
1037*795d594fSAndroid Build Coastguard Worker     MethodType methodType2 = MethodType.methodType(int.class,
1038*795d594fSAndroid Build Coastguard Worker         new Class<?>[] { String.class, int.class });
1039*795d594fSAndroid Build Coastguard Worker     MethodHandle delegate2 = MethodHandles.lookup().findStatic(
1040*795d594fSAndroid Build Coastguard Worker         Main.class, "spreadReferences_Unbox", methodType2);
1041*795d594fSAndroid Build Coastguard Worker 
1042*795d594fSAndroid Build Coastguard Worker     // .. with an Integer[] array.
1043*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate2.asSpreader(Integer[].class, 1);
1044*795d594fSAndroid Build Coastguard Worker     ret = (int) mhAsSpreader.invoke("a", new Integer[] { 43 });
1045*795d594fSAndroid Build Coastguard Worker     assertEquals(43, ret);
1046*795d594fSAndroid Build Coastguard Worker 
1047*795d594fSAndroid Build Coastguard Worker     // .. with an Integer[] array declared as an Object[] argument type.
1048*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate2.asSpreader(Object[].class, 1);
1049*795d594fSAndroid Build Coastguard Worker     ret = (int) mhAsSpreader.invoke("a", new Integer[] { 43 });
1050*795d594fSAndroid Build Coastguard Worker     assertEquals(43, ret);
1051*795d594fSAndroid Build Coastguard Worker 
1052*795d594fSAndroid Build Coastguard Worker     // .. with an Object[] array.
1053*795d594fSAndroid Build Coastguard Worker     mhAsSpreader = delegate2.asSpreader(Object[].class, 1);
1054*795d594fSAndroid Build Coastguard Worker     ret = (int) mhAsSpreader.invoke("a", new Object[] { Integer.valueOf(43)});
1055*795d594fSAndroid Build Coastguard Worker     assertEquals(43, ret);
1056*795d594fSAndroid Build Coastguard Worker 
1057*795d594fSAndroid Build Coastguard Worker     // -- Part 2--
1058*795d594fSAndroid Build Coastguard Worker     // Run a subset of these tests on MethodHandles.spreadInvoker, which only accepts
1059*795d594fSAndroid Build Coastguard Worker     // a trailing argument type of Object[].
1060*795d594fSAndroid Build Coastguard Worker     MethodHandle spreadInvoker = MethodHandles.spreadInvoker(methodType2, 1);
1061*795d594fSAndroid Build Coastguard Worker     ret = (int) spreadInvoker.invoke(delegate2, "a", new Object[] { Integer.valueOf(43)});
1062*795d594fSAndroid Build Coastguard Worker     assertEquals(43, ret);
1063*795d594fSAndroid Build Coastguard Worker 
1064*795d594fSAndroid Build Coastguard Worker     ret = (int) spreadInvoker.invoke(delegate2, "a", new Integer[] { 43 });
1065*795d594fSAndroid Build Coastguard Worker     assertEquals(43, ret);
1066*795d594fSAndroid Build Coastguard Worker 
1067*795d594fSAndroid Build Coastguard Worker     // NOTE: Annoyingly, the second argument here is leadingArgCount and not
1068*795d594fSAndroid Build Coastguard Worker     // arrayLength.
1069*795d594fSAndroid Build Coastguard Worker     spreadInvoker = MethodHandles.spreadInvoker(methodType, 3);
1070*795d594fSAndroid Build Coastguard Worker     ret = (int) spreadInvoker.invoke(delegate, "a", "b", "c", new String[] {});
1071*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
1072*795d594fSAndroid Build Coastguard Worker 
1073*795d594fSAndroid Build Coastguard Worker     spreadInvoker = MethodHandles.spreadInvoker(methodType, 0);
1074*795d594fSAndroid Build Coastguard Worker     ret = (int) spreadInvoker.invoke(delegate, new String[] { "a", "b", "c" });
1075*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
1076*795d594fSAndroid Build Coastguard Worker 
1077*795d594fSAndroid Build Coastguard Worker     // Exact invokes: Double check that the expected parameter type is
1078*795d594fSAndroid Build Coastguard Worker     // Object[] and not T[].
1079*795d594fSAndroid Build Coastguard Worker     try {
1080*795d594fSAndroid Build Coastguard Worker       spreadInvoker.invokeExact(delegate, new String[] { "a", "b", "c" });
1081*795d594fSAndroid Build Coastguard Worker       fail();
1082*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
1083*795d594fSAndroid Build Coastguard Worker     }
1084*795d594fSAndroid Build Coastguard Worker 
1085*795d594fSAndroid Build Coastguard Worker     ret = (int) spreadInvoker.invoke(delegate, new Object[] { "a", "b", "c" });
1086*795d594fSAndroid Build Coastguard Worker     assertEquals(42, ret);
1087*795d594fSAndroid Build Coastguard Worker   }
1088*795d594fSAndroid Build Coastguard Worker 
spreadBoolean(String a, Boolean b, boolean c)1089*795d594fSAndroid Build Coastguard Worker   public static int spreadBoolean(String a, Boolean b, boolean c) {
1090*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c: " + c);
1091*795d594fSAndroid Build Coastguard Worker     return 44;
1092*795d594fSAndroid Build Coastguard Worker   }
1093*795d594fSAndroid Build Coastguard Worker 
spreadByte(String a, Byte b, byte c, short d, int e, long f, float g, double h)1094*795d594fSAndroid Build Coastguard Worker   public static int spreadByte(String a, Byte b, byte c,
1095*795d594fSAndroid Build Coastguard Worker       short d, int e, long f, float g, double h) {
1096*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c: " + c +
1097*795d594fSAndroid Build Coastguard Worker         ", d: " + d + ", e: " + e + ", f:" + f + ", g: " + g +
1098*795d594fSAndroid Build Coastguard Worker         ", h: " + h);
1099*795d594fSAndroid Build Coastguard Worker     return 45;
1100*795d594fSAndroid Build Coastguard Worker   }
1101*795d594fSAndroid Build Coastguard Worker 
spreadChar(String a, Character b, char c, int d, long e, float f, double g)1102*795d594fSAndroid Build Coastguard Worker   public static int spreadChar(String a, Character b, char c,
1103*795d594fSAndroid Build Coastguard Worker       int d, long e, float f, double g) {
1104*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c: " + c +
1105*795d594fSAndroid Build Coastguard Worker         ", d: " + d + ", e: " + e + ", f:" + f + ", g: " + g);
1106*795d594fSAndroid Build Coastguard Worker     return 46;
1107*795d594fSAndroid Build Coastguard Worker   }
1108*795d594fSAndroid Build Coastguard Worker 
spreadShort(String a, Short b, short c, int d, long e, float f, double g)1109*795d594fSAndroid Build Coastguard Worker   public static int spreadShort(String a, Short b, short c,
1110*795d594fSAndroid Build Coastguard Worker       int d, long e, float f, double g) {
1111*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c: " + c +
1112*795d594fSAndroid Build Coastguard Worker         ", d: " + d + ", e: " + e + ", f:" + f + ", g:" + g);
1113*795d594fSAndroid Build Coastguard Worker     return 47;
1114*795d594fSAndroid Build Coastguard Worker   }
1115*795d594fSAndroid Build Coastguard Worker 
spreadInt(String a, Integer b, int c, long d, float e, double f)1116*795d594fSAndroid Build Coastguard Worker   public static int spreadInt(String a, Integer b, int c,
1117*795d594fSAndroid Build Coastguard Worker       long d, float e, double f) {
1118*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c: " + c +
1119*795d594fSAndroid Build Coastguard Worker         ", d: " + d + ", e: " + e + ", f:" + f);
1120*795d594fSAndroid Build Coastguard Worker     return 48;
1121*795d594fSAndroid Build Coastguard Worker   }
1122*795d594fSAndroid Build Coastguard Worker 
spreadLong(String a, Long b, long c, float d, double e)1123*795d594fSAndroid Build Coastguard Worker   public static int spreadLong(String a, Long b, long c, float d, double e) {
1124*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c: " + c +
1125*795d594fSAndroid Build Coastguard Worker         ", d: " + d + ", e: " + e);
1126*795d594fSAndroid Build Coastguard Worker     return 49;
1127*795d594fSAndroid Build Coastguard Worker   }
1128*795d594fSAndroid Build Coastguard Worker 
spreadFloat(String a, Float b, float c, double d)1129*795d594fSAndroid Build Coastguard Worker   public static int spreadFloat(String a, Float b, float c, double d) {
1130*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c: " + c + ", d: " + d);
1131*795d594fSAndroid Build Coastguard Worker     return 50;
1132*795d594fSAndroid Build Coastguard Worker   }
1133*795d594fSAndroid Build Coastguard Worker 
spreadDouble(String a, Double b, double c)1134*795d594fSAndroid Build Coastguard Worker   public static int spreadDouble(String a, Double b, double c) {
1135*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c: " + c);
1136*795d594fSAndroid Build Coastguard Worker     return 51;
1137*795d594fSAndroid Build Coastguard Worker   }
1138*795d594fSAndroid Build Coastguard Worker 
testSpreaders_primitive()1139*795d594fSAndroid Build Coastguard Worker   public static void testSpreaders_primitive() throws Throwable {
1140*795d594fSAndroid Build Coastguard Worker     // boolean[]
1141*795d594fSAndroid Build Coastguard Worker     // ---------------------
1142*795d594fSAndroid Build Coastguard Worker     MethodType type = MethodType.methodType(int.class,
1143*795d594fSAndroid Build Coastguard Worker         new Class<?>[] { String.class, Boolean.class, boolean.class });
1144*795d594fSAndroid Build Coastguard Worker     MethodHandle delegate = MethodHandles.lookup().findStatic(
1145*795d594fSAndroid Build Coastguard Worker         Main.class, "spreadBoolean", type);
1146*795d594fSAndroid Build Coastguard Worker 
1147*795d594fSAndroid Build Coastguard Worker     MethodHandle spreader = delegate.asSpreader(boolean[].class, 2);
1148*795d594fSAndroid Build Coastguard Worker     int ret = (int) spreader.invokeExact("a", new boolean[] { true, false });
1149*795d594fSAndroid Build Coastguard Worker     assertEquals(44, ret);
1150*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invoke("a", new boolean[] { true, false });
1151*795d594fSAndroid Build Coastguard Worker     assertEquals(44, ret);
1152*795d594fSAndroid Build Coastguard Worker 
1153*795d594fSAndroid Build Coastguard Worker     // boolean can't be cast to String (the first argument to the method).
1154*795d594fSAndroid Build Coastguard Worker     try {
1155*795d594fSAndroid Build Coastguard Worker       delegate.asSpreader(boolean[].class, 3);
1156*795d594fSAndroid Build Coastguard Worker       fail();
1157*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
1158*795d594fSAndroid Build Coastguard Worker     }
1159*795d594fSAndroid Build Coastguard Worker 
1160*795d594fSAndroid Build Coastguard Worker     // int can't be cast to boolean to supply the last argument to the method.
1161*795d594fSAndroid Build Coastguard Worker     try {
1162*795d594fSAndroid Build Coastguard Worker       delegate.asSpreader(int[].class, 1);
1163*795d594fSAndroid Build Coastguard Worker       fail();
1164*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
1165*795d594fSAndroid Build Coastguard Worker     }
1166*795d594fSAndroid Build Coastguard Worker 
1167*795d594fSAndroid Build Coastguard Worker     // byte[]
1168*795d594fSAndroid Build Coastguard Worker     // ---------------------
1169*795d594fSAndroid Build Coastguard Worker     type = MethodType.methodType(int.class,
1170*795d594fSAndroid Build Coastguard Worker         new Class<?>[] {
1171*795d594fSAndroid Build Coastguard Worker           String.class, Byte.class, byte.class,
1172*795d594fSAndroid Build Coastguard Worker           short.class, int.class, long.class,
1173*795d594fSAndroid Build Coastguard Worker           float.class, double.class });
1174*795d594fSAndroid Build Coastguard Worker     delegate = MethodHandles.lookup().findStatic(Main.class, "spreadByte", type);
1175*795d594fSAndroid Build Coastguard Worker 
1176*795d594fSAndroid Build Coastguard Worker     spreader = delegate.asSpreader(byte[].class, 7);
1177*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a",
1178*795d594fSAndroid Build Coastguard Worker         new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 });
1179*795d594fSAndroid Build Coastguard Worker     assertEquals(45, ret);
1180*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invoke("a",
1181*795d594fSAndroid Build Coastguard Worker         new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 });
1182*795d594fSAndroid Build Coastguard Worker     assertEquals(45, ret);
1183*795d594fSAndroid Build Coastguard Worker 
1184*795d594fSAndroid Build Coastguard Worker     // char[]
1185*795d594fSAndroid Build Coastguard Worker     // ---------------------
1186*795d594fSAndroid Build Coastguard Worker     type = MethodType.methodType(int.class,
1187*795d594fSAndroid Build Coastguard Worker         new Class<?>[] {
1188*795d594fSAndroid Build Coastguard Worker           String.class, Character.class,char.class,
1189*795d594fSAndroid Build Coastguard Worker           int.class, long.class, float.class, double.class });
1190*795d594fSAndroid Build Coastguard Worker     delegate = MethodHandles.lookup().findStatic(Main.class, "spreadChar", type);
1191*795d594fSAndroid Build Coastguard Worker 
1192*795d594fSAndroid Build Coastguard Worker     spreader = delegate.asSpreader(char[].class, 6);
1193*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a",
1194*795d594fSAndroid Build Coastguard Worker         new char[] { '1', '2', '3', '4', '5', '6' });
1195*795d594fSAndroid Build Coastguard Worker     assertEquals(46, ret);
1196*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a",
1197*795d594fSAndroid Build Coastguard Worker         new char[] { '1', '2', '3', '4', '5', '6' });
1198*795d594fSAndroid Build Coastguard Worker     assertEquals(46, ret);
1199*795d594fSAndroid Build Coastguard Worker 
1200*795d594fSAndroid Build Coastguard Worker     // short[]
1201*795d594fSAndroid Build Coastguard Worker     // ---------------------
1202*795d594fSAndroid Build Coastguard Worker     type = MethodType.methodType(int.class,
1203*795d594fSAndroid Build Coastguard Worker         new Class<?>[] {
1204*795d594fSAndroid Build Coastguard Worker           String.class, Short.class, short.class,
1205*795d594fSAndroid Build Coastguard Worker           int.class, long.class, float.class, double.class });
1206*795d594fSAndroid Build Coastguard Worker     delegate = MethodHandles.lookup().findStatic(Main.class, "spreadShort", type);
1207*795d594fSAndroid Build Coastguard Worker 
1208*795d594fSAndroid Build Coastguard Worker     spreader = delegate.asSpreader(short[].class, 6);
1209*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a",
1210*795d594fSAndroid Build Coastguard Worker         new short[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 });
1211*795d594fSAndroid Build Coastguard Worker     assertEquals(47, ret);
1212*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invoke("a",
1213*795d594fSAndroid Build Coastguard Worker         new short[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 });
1214*795d594fSAndroid Build Coastguard Worker     assertEquals(47, ret);
1215*795d594fSAndroid Build Coastguard Worker 
1216*795d594fSAndroid Build Coastguard Worker     // int[]
1217*795d594fSAndroid Build Coastguard Worker     // ---------------------
1218*795d594fSAndroid Build Coastguard Worker     type = MethodType.methodType(int.class,
1219*795d594fSAndroid Build Coastguard Worker         new Class<?>[] {
1220*795d594fSAndroid Build Coastguard Worker           String.class, Integer.class, int.class,
1221*795d594fSAndroid Build Coastguard Worker           long.class, float.class, double.class });
1222*795d594fSAndroid Build Coastguard Worker     delegate = MethodHandles.lookup().findStatic(Main.class, "spreadInt", type);
1223*795d594fSAndroid Build Coastguard Worker 
1224*795d594fSAndroid Build Coastguard Worker     spreader = delegate.asSpreader(int[].class, 5);
1225*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a", new int[] { 1, 2, 3, 4, 5 });
1226*795d594fSAndroid Build Coastguard Worker     assertEquals(48, ret);
1227*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a", new int[] { 1, 2, 3, 4, 5 });
1228*795d594fSAndroid Build Coastguard Worker     assertEquals(48, ret);
1229*795d594fSAndroid Build Coastguard Worker 
1230*795d594fSAndroid Build Coastguard Worker     // long[]
1231*795d594fSAndroid Build Coastguard Worker     // ---------------------
1232*795d594fSAndroid Build Coastguard Worker     type = MethodType.methodType(int.class,
1233*795d594fSAndroid Build Coastguard Worker         new Class<?>[] {
1234*795d594fSAndroid Build Coastguard Worker           String.class, Long.class, long.class, float.class, double.class });
1235*795d594fSAndroid Build Coastguard Worker     delegate = MethodHandles.lookup().findStatic(Main.class, "spreadLong", type);
1236*795d594fSAndroid Build Coastguard Worker 
1237*795d594fSAndroid Build Coastguard Worker     spreader = delegate.asSpreader(long[].class, 4);
1238*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a",
1239*795d594fSAndroid Build Coastguard Worker         new long[] { 0x1, 0x2, 0x3, 0x4 });
1240*795d594fSAndroid Build Coastguard Worker     assertEquals(49, ret);
1241*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invoke("a",
1242*795d594fSAndroid Build Coastguard Worker         new long[] { 0x1, 0x2, 0x3, 0x4 });
1243*795d594fSAndroid Build Coastguard Worker     assertEquals(49, ret);
1244*795d594fSAndroid Build Coastguard Worker 
1245*795d594fSAndroid Build Coastguard Worker     // float[]
1246*795d594fSAndroid Build Coastguard Worker     // ---------------------
1247*795d594fSAndroid Build Coastguard Worker     type = MethodType.methodType(int.class,
1248*795d594fSAndroid Build Coastguard Worker         new Class<?>[] {
1249*795d594fSAndroid Build Coastguard Worker           String.class, Float.class, float.class, double.class });
1250*795d594fSAndroid Build Coastguard Worker     delegate = MethodHandles.lookup().findStatic(Main.class, "spreadFloat", type);
1251*795d594fSAndroid Build Coastguard Worker 
1252*795d594fSAndroid Build Coastguard Worker     spreader = delegate.asSpreader(float[].class, 3);
1253*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a",
1254*795d594fSAndroid Build Coastguard Worker         new float[] { 1.0f, 2.0f, 3.0f });
1255*795d594fSAndroid Build Coastguard Worker     assertEquals(50, ret);
1256*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a",
1257*795d594fSAndroid Build Coastguard Worker         new float[] { 1.0f, 2.0f, 3.0f });
1258*795d594fSAndroid Build Coastguard Worker     assertEquals(50, ret);
1259*795d594fSAndroid Build Coastguard Worker 
1260*795d594fSAndroid Build Coastguard Worker     // double[]
1261*795d594fSAndroid Build Coastguard Worker     // ---------------------
1262*795d594fSAndroid Build Coastguard Worker     type = MethodType.methodType(int.class,
1263*795d594fSAndroid Build Coastguard Worker         new Class<?>[] { String.class, Double.class, double.class });
1264*795d594fSAndroid Build Coastguard Worker     delegate = MethodHandles.lookup().findStatic(Main.class, "spreadDouble", type);
1265*795d594fSAndroid Build Coastguard Worker 
1266*795d594fSAndroid Build Coastguard Worker     spreader = delegate.asSpreader(double[].class, 2);
1267*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a", new double[] { 1.0, 2.0 });
1268*795d594fSAndroid Build Coastguard Worker     assertEquals(51, ret);
1269*795d594fSAndroid Build Coastguard Worker     ret = (int) spreader.invokeExact("a", new double[] { 1.0, 2.0 });
1270*795d594fSAndroid Build Coastguard Worker     assertEquals(51, ret);
1271*795d594fSAndroid Build Coastguard Worker   }
1272*795d594fSAndroid Build Coastguard Worker 
testInvokeWithArguments()1273*795d594fSAndroid Build Coastguard Worker   public static void testInvokeWithArguments() throws Throwable {
1274*795d594fSAndroid Build Coastguard Worker     MethodType methodType = MethodType.methodType(int.class,
1275*795d594fSAndroid Build Coastguard Worker         new Class<?>[] { String.class, String.class, String.class });
1276*795d594fSAndroid Build Coastguard Worker     MethodHandle handle = MethodHandles.lookup().findStatic(
1277*795d594fSAndroid Build Coastguard Worker         Main.class, "spreadReferences", methodType);
1278*795d594fSAndroid Build Coastguard Worker 
1279*795d594fSAndroid Build Coastguard Worker     Object ret = handle.invokeWithArguments(new Object[] { "a", "b", "c"});
1280*795d594fSAndroid Build Coastguard Worker     assertEquals(42, (int) ret);
1281*795d594fSAndroid Build Coastguard Worker     handle.invokeWithArguments(new String[] { "a", "b", "c" });
1282*795d594fSAndroid Build Coastguard Worker     assertEquals(42, (int) ret);
1283*795d594fSAndroid Build Coastguard Worker 
1284*795d594fSAndroid Build Coastguard Worker     // Pass in an array that's too small. Should throw an IAE.
1285*795d594fSAndroid Build Coastguard Worker     try {
1286*795d594fSAndroid Build Coastguard Worker       handle.invokeWithArguments(new Object[] { "a", "b" });
1287*795d594fSAndroid Build Coastguard Worker       fail();
1288*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1289*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
1290*795d594fSAndroid Build Coastguard Worker     }
1291*795d594fSAndroid Build Coastguard Worker 
1292*795d594fSAndroid Build Coastguard Worker     // Test implicit unboxing.
1293*795d594fSAndroid Build Coastguard Worker     MethodType methodType2 = MethodType.methodType(int.class,
1294*795d594fSAndroid Build Coastguard Worker         new Class<?>[] { String.class, int.class });
1295*795d594fSAndroid Build Coastguard Worker     MethodHandle handle2 = MethodHandles.lookup().findStatic(
1296*795d594fSAndroid Build Coastguard Worker         Main.class, "spreadReferences_Unbox", methodType2);
1297*795d594fSAndroid Build Coastguard Worker 
1298*795d594fSAndroid Build Coastguard Worker     ret = (int) handle2.invokeWithArguments(new Object[] { "a", 43 });
1299*795d594fSAndroid Build Coastguard Worker     assertEquals(43, (int) ret);
1300*795d594fSAndroid Build Coastguard Worker   }
1301*795d594fSAndroid Build Coastguard Worker 
collectBoolean(String a, boolean[] b)1302*795d594fSAndroid Build Coastguard Worker   public static int collectBoolean(String a, boolean[] b) {
1303*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b[0] + ", c: " + b[1]);
1304*795d594fSAndroid Build Coastguard Worker     return 44;
1305*795d594fSAndroid Build Coastguard Worker   }
1306*795d594fSAndroid Build Coastguard Worker 
collectByte(String a, byte[] b)1307*795d594fSAndroid Build Coastguard Worker   public static int collectByte(String a, byte[] b) {
1308*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b[0] + ", c: " + b[1]);
1309*795d594fSAndroid Build Coastguard Worker     return 45;
1310*795d594fSAndroid Build Coastguard Worker   }
1311*795d594fSAndroid Build Coastguard Worker 
collectChar(String a, char[] b)1312*795d594fSAndroid Build Coastguard Worker   public static int collectChar(String a, char[] b) {
1313*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b[0] + ", c: " + b[1]);
1314*795d594fSAndroid Build Coastguard Worker     return 46;
1315*795d594fSAndroid Build Coastguard Worker   }
1316*795d594fSAndroid Build Coastguard Worker 
collectShort(String a, short[] b)1317*795d594fSAndroid Build Coastguard Worker   public static int collectShort(String a, short[] b) {
1318*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b[0] + ", c: " + b[1]);
1319*795d594fSAndroid Build Coastguard Worker     return 47;
1320*795d594fSAndroid Build Coastguard Worker   }
1321*795d594fSAndroid Build Coastguard Worker 
collectInt(String a, int[] b)1322*795d594fSAndroid Build Coastguard Worker   public static int collectInt(String a, int[] b) {
1323*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b[0] + ", c: " + b[1]);
1324*795d594fSAndroid Build Coastguard Worker     return 48;
1325*795d594fSAndroid Build Coastguard Worker   }
1326*795d594fSAndroid Build Coastguard Worker 
collectLong(String a, long[] b)1327*795d594fSAndroid Build Coastguard Worker   public static int collectLong(String a, long[] b) {
1328*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b[0] + ", c: " + b[1]);
1329*795d594fSAndroid Build Coastguard Worker     return 49;
1330*795d594fSAndroid Build Coastguard Worker   }
1331*795d594fSAndroid Build Coastguard Worker 
collectFloat(String a, float[] b)1332*795d594fSAndroid Build Coastguard Worker   public static int collectFloat(String a, float[] b) {
1333*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b[0] + ", c: " + b[1]);
1334*795d594fSAndroid Build Coastguard Worker     return 50;
1335*795d594fSAndroid Build Coastguard Worker   }
1336*795d594fSAndroid Build Coastguard Worker 
collectDouble(String a, double[] b)1337*795d594fSAndroid Build Coastguard Worker   public static int collectDouble(String a, double[] b) {
1338*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b[0] + ", c: " + b[1]);
1339*795d594fSAndroid Build Coastguard Worker     return 51;
1340*795d594fSAndroid Build Coastguard Worker   }
1341*795d594fSAndroid Build Coastguard Worker 
collectCharSequence(String a, CharSequence[] b)1342*795d594fSAndroid Build Coastguard Worker   public static int collectCharSequence(String a, CharSequence[] b) {
1343*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b[0] + ", c: " + b[1]);
1344*795d594fSAndroid Build Coastguard Worker     return 99;
1345*795d594fSAndroid Build Coastguard Worker   }
1346*795d594fSAndroid Build Coastguard Worker 
testAsCollector()1347*795d594fSAndroid Build Coastguard Worker   public static void testAsCollector() throws Throwable {
1348*795d594fSAndroid Build Coastguard Worker     // Reference arrays.
1349*795d594fSAndroid Build Coastguard Worker     // -------------------
1350*795d594fSAndroid Build Coastguard Worker     MethodHandle trailingRef = MethodHandles.lookup().findStatic(
1351*795d594fSAndroid Build Coastguard Worker         Main.class, "collectCharSequence",
1352*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, CharSequence[].class));
1353*795d594fSAndroid Build Coastguard Worker 
1354*795d594fSAndroid Build Coastguard Worker     // int[] is not convertible to CharSequence[].class.
1355*795d594fSAndroid Build Coastguard Worker     try {
1356*795d594fSAndroid Build Coastguard Worker       trailingRef.asCollector(int[].class, 1);
1357*795d594fSAndroid Build Coastguard Worker       fail();
1358*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1359*795d594fSAndroid Build Coastguard Worker     }
1360*795d594fSAndroid Build Coastguard Worker 
1361*795d594fSAndroid Build Coastguard Worker     // Object[] is not convertible to CharSequence[].class.
1362*795d594fSAndroid Build Coastguard Worker     try {
1363*795d594fSAndroid Build Coastguard Worker       trailingRef.asCollector(Object[].class, 1);
1364*795d594fSAndroid Build Coastguard Worker       fail();
1365*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1366*795d594fSAndroid Build Coastguard Worker     }
1367*795d594fSAndroid Build Coastguard Worker 
1368*795d594fSAndroid Build Coastguard Worker     // String[].class is convertible to CharSequence.class
1369*795d594fSAndroid Build Coastguard Worker     MethodHandle collector = trailingRef.asCollector(String[].class, 2);
1370*795d594fSAndroid Build Coastguard Worker     assertEquals(99, (int) collector.invoke("a", "b", "c"));
1371*795d594fSAndroid Build Coastguard Worker 
1372*795d594fSAndroid Build Coastguard Worker     // Too few arguments should fail with a WMTE.
1373*795d594fSAndroid Build Coastguard Worker     try {
1374*795d594fSAndroid Build Coastguard Worker       collector.invoke("a", "b");
1375*795d594fSAndroid Build Coastguard Worker       fail();
1376*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
1377*795d594fSAndroid Build Coastguard Worker     }
1378*795d594fSAndroid Build Coastguard Worker 
1379*795d594fSAndroid Build Coastguard Worker     // Too many arguments should fail with a WMTE.
1380*795d594fSAndroid Build Coastguard Worker     try {
1381*795d594fSAndroid Build Coastguard Worker       collector.invoke("a", "b", "c", "d");
1382*795d594fSAndroid Build Coastguard Worker       fail();
1383*795d594fSAndroid Build Coastguard Worker     } catch (WrongMethodTypeException expected) {
1384*795d594fSAndroid Build Coastguard Worker     }
1385*795d594fSAndroid Build Coastguard Worker 
1386*795d594fSAndroid Build Coastguard Worker     // Checks on other array types.
1387*795d594fSAndroid Build Coastguard Worker 
1388*795d594fSAndroid Build Coastguard Worker     MethodHandle target = MethodHandles.lookup().findStatic(
1389*795d594fSAndroid Build Coastguard Worker         Main.class, "collectBoolean",
1390*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, boolean[].class));
1391*795d594fSAndroid Build Coastguard Worker     assertEquals(44, (int) target.asCollector(boolean[].class, 2).invoke("a", true, false));
1392*795d594fSAndroid Build Coastguard Worker 
1393*795d594fSAndroid Build Coastguard Worker     target = MethodHandles.lookup().findStatic(Main.class, "collectByte",
1394*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, byte[].class));
1395*795d594fSAndroid Build Coastguard Worker     assertEquals(45, (int) target.asCollector(byte[].class, 2).invoke("a", (byte) 1, (byte) 2));
1396*795d594fSAndroid Build Coastguard Worker 
1397*795d594fSAndroid Build Coastguard Worker     target = MethodHandles.lookup().findStatic(Main.class, "collectChar",
1398*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, char[].class));
1399*795d594fSAndroid Build Coastguard Worker     assertEquals(46, (int) target.asCollector(char[].class, 2).invoke("a", 'a', 'b'));
1400*795d594fSAndroid Build Coastguard Worker 
1401*795d594fSAndroid Build Coastguard Worker     target = MethodHandles.lookup().findStatic(Main.class, "collectShort",
1402*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, short[].class));
1403*795d594fSAndroid Build Coastguard Worker     assertEquals(47, (int) target.asCollector(short[].class, 2).invoke("a", (short) 3, (short) 4));
1404*795d594fSAndroid Build Coastguard Worker 
1405*795d594fSAndroid Build Coastguard Worker     target = MethodHandles.lookup().findStatic(Main.class, "collectInt",
1406*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, int[].class));
1407*795d594fSAndroid Build Coastguard Worker     assertEquals(48, (int) target.asCollector(int[].class, 2).invoke("a", 42, 43));
1408*795d594fSAndroid Build Coastguard Worker 
1409*795d594fSAndroid Build Coastguard Worker     target = MethodHandles.lookup().findStatic(Main.class, "collectLong",
1410*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, long[].class));
1411*795d594fSAndroid Build Coastguard Worker     assertEquals(49, (int) target.asCollector(long[].class, 2).invoke("a", 100, 99));
1412*795d594fSAndroid Build Coastguard Worker 
1413*795d594fSAndroid Build Coastguard Worker     target = MethodHandles.lookup().findStatic(Main.class, "collectFloat",
1414*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, float[].class));
1415*795d594fSAndroid Build Coastguard Worker     assertEquals(50, (int) target.asCollector(float[].class, 2).invoke("a", 8.9f, 9.1f));
1416*795d594fSAndroid Build Coastguard Worker 
1417*795d594fSAndroid Build Coastguard Worker     target = MethodHandles.lookup().findStatic(Main.class, "collectDouble",
1418*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, double[].class));
1419*795d594fSAndroid Build Coastguard Worker     assertEquals(51, (int) target.asCollector(double[].class, 2).invoke("a", 6.7, 7.8));
1420*795d594fSAndroid Build Coastguard Worker   }
1421*795d594fSAndroid Build Coastguard Worker 
filter1(char a)1422*795d594fSAndroid Build Coastguard Worker   public static String filter1(char a) {
1423*795d594fSAndroid Build Coastguard Worker     return String.valueOf(a);
1424*795d594fSAndroid Build Coastguard Worker   }
1425*795d594fSAndroid Build Coastguard Worker 
filter2(String b)1426*795d594fSAndroid Build Coastguard Worker   public static char filter2(String b) {
1427*795d594fSAndroid Build Coastguard Worker     return b.charAt(0);
1428*795d594fSAndroid Build Coastguard Worker   }
1429*795d594fSAndroid Build Coastguard Worker 
badFilter1(char a, char b)1430*795d594fSAndroid Build Coastguard Worker   public static String badFilter1(char a, char b) {
1431*795d594fSAndroid Build Coastguard Worker     return "bad";
1432*795d594fSAndroid Build Coastguard Worker   }
1433*795d594fSAndroid Build Coastguard Worker 
filterTarget(String a, char b, String c, char d)1434*795d594fSAndroid Build Coastguard Worker   public static int filterTarget(String a, char b, String c, char d) {
1435*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b: " + b + ", c:" + c + ", d:" + d);
1436*795d594fSAndroid Build Coastguard Worker     return 56;
1437*795d594fSAndroid Build Coastguard Worker   }
1438*795d594fSAndroid Build Coastguard Worker 
testFilterArguments()1439*795d594fSAndroid Build Coastguard Worker   public static void testFilterArguments() throws Throwable {
1440*795d594fSAndroid Build Coastguard Worker     MethodHandle filter1 = MethodHandles.lookup().findStatic(
1441*795d594fSAndroid Build Coastguard Worker         Main.class, "filter1", MethodType.methodType(String.class, char.class));
1442*795d594fSAndroid Build Coastguard Worker     MethodHandle filter2 = MethodHandles.lookup().findStatic(
1443*795d594fSAndroid Build Coastguard Worker         Main.class, "filter2", MethodType.methodType(char.class, String.class));
1444*795d594fSAndroid Build Coastguard Worker 
1445*795d594fSAndroid Build Coastguard Worker     MethodHandle target = MethodHandles.lookup().findStatic(
1446*795d594fSAndroid Build Coastguard Worker         Main.class, "filterTarget", MethodType.methodType(int.class,
1447*795d594fSAndroid Build Coastguard Worker           String.class, char.class, String.class, char.class));
1448*795d594fSAndroid Build Coastguard Worker 
1449*795d594fSAndroid Build Coastguard Worker     // In all the cases below, the values printed will be 'a', 'b', 'c', 'd'.
1450*795d594fSAndroid Build Coastguard Worker 
1451*795d594fSAndroid Build Coastguard Worker     // Filter arguments [0, 1] - all other arguments are passed through
1452*795d594fSAndroid Build Coastguard Worker     // as is.
1453*795d594fSAndroid Build Coastguard Worker     MethodHandle adapter = MethodHandles.filterArguments(
1454*795d594fSAndroid Build Coastguard Worker         target, 0, filter1, filter2);
1455*795d594fSAndroid Build Coastguard Worker     assertEquals(56, (int) adapter.invokeExact('a', "bXXXX", "c", 'd'));
1456*795d594fSAndroid Build Coastguard Worker 
1457*795d594fSAndroid Build Coastguard Worker     // Filter arguments [1, 2].
1458*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.filterArguments(target, 1, filter2, filter1);
1459*795d594fSAndroid Build Coastguard Worker     assertEquals(56, (int) adapter.invokeExact("a", "bXXXX", 'c', 'd'));
1460*795d594fSAndroid Build Coastguard Worker 
1461*795d594fSAndroid Build Coastguard Worker     // Filter arguments [2, 3].
1462*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.filterArguments(target, 2, filter1, filter2);
1463*795d594fSAndroid Build Coastguard Worker     assertEquals(56, (int) adapter.invokeExact("a", 'b', 'c', "dXXXXX"));
1464*795d594fSAndroid Build Coastguard Worker 
1465*795d594fSAndroid Build Coastguard Worker     // Try out a few error cases :
1466*795d594fSAndroid Build Coastguard Worker 
1467*795d594fSAndroid Build Coastguard Worker     // The return types of the filter doesn't align with the expected argument
1468*795d594fSAndroid Build Coastguard Worker     // type of the target.
1469*795d594fSAndroid Build Coastguard Worker     try {
1470*795d594fSAndroid Build Coastguard Worker       adapter = MethodHandles.filterArguments(target, 2, filter2, filter1);
1471*795d594fSAndroid Build Coastguard Worker       fail();
1472*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1473*795d594fSAndroid Build Coastguard Worker     }
1474*795d594fSAndroid Build Coastguard Worker 
1475*795d594fSAndroid Build Coastguard Worker     // There are more filters than arguments.
1476*795d594fSAndroid Build Coastguard Worker     try {
1477*795d594fSAndroid Build Coastguard Worker       adapter = MethodHandles.filterArguments(target, 3, filter2, filter1);
1478*795d594fSAndroid Build Coastguard Worker       fail();
1479*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1480*795d594fSAndroid Build Coastguard Worker     }
1481*795d594fSAndroid Build Coastguard Worker 
1482*795d594fSAndroid Build Coastguard Worker     // We pass in an obviously bogus position.
1483*795d594fSAndroid Build Coastguard Worker     try {
1484*795d594fSAndroid Build Coastguard Worker       adapter = MethodHandles.filterArguments(target, -1, filter2, filter1);
1485*795d594fSAndroid Build Coastguard Worker       fail();
1486*795d594fSAndroid Build Coastguard Worker     } catch (ArrayIndexOutOfBoundsException expected) {
1487*795d594fSAndroid Build Coastguard Worker     }
1488*795d594fSAndroid Build Coastguard Worker 
1489*795d594fSAndroid Build Coastguard Worker     // We pass in a function that has more than one argument.
1490*795d594fSAndroid Build Coastguard Worker     MethodHandle badFilter1 = MethodHandles.lookup().findStatic(
1491*795d594fSAndroid Build Coastguard Worker         Main.class, "badFilter1",
1492*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(String.class, char.class, char.class));
1493*795d594fSAndroid Build Coastguard Worker 
1494*795d594fSAndroid Build Coastguard Worker     try {
1495*795d594fSAndroid Build Coastguard Worker       adapter = MethodHandles.filterArguments(target, 0, badFilter1, filter2);
1496*795d594fSAndroid Build Coastguard Worker       fail();
1497*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1498*795d594fSAndroid Build Coastguard Worker     }
1499*795d594fSAndroid Build Coastguard Worker   }
1500*795d594fSAndroid Build Coastguard Worker 
voidFilter(char a, char b)1501*795d594fSAndroid Build Coastguard Worker   static void voidFilter(char a, char b) {
1502*795d594fSAndroid Build Coastguard Worker     System.out.println("voidFilter");
1503*795d594fSAndroid Build Coastguard Worker   }
1504*795d594fSAndroid Build Coastguard Worker 
filter(char a, char b)1505*795d594fSAndroid Build Coastguard Worker   static String filter(char a, char b) {
1506*795d594fSAndroid Build Coastguard Worker     return String.valueOf(a) + "+" + b;
1507*795d594fSAndroid Build Coastguard Worker   }
1508*795d594fSAndroid Build Coastguard Worker 
badFilter(char a, char b)1509*795d594fSAndroid Build Coastguard Worker   static char badFilter(char a, char b) {
1510*795d594fSAndroid Build Coastguard Worker     return 0;
1511*795d594fSAndroid Build Coastguard Worker   }
1512*795d594fSAndroid Build Coastguard Worker 
target(String a, String b, String c)1513*795d594fSAndroid Build Coastguard Worker   static int target(String a, String b, String c) {
1514*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b: " + b + ", c: " + c);
1515*795d594fSAndroid Build Coastguard Worker     return 57;
1516*795d594fSAndroid Build Coastguard Worker   }
1517*795d594fSAndroid Build Coastguard Worker 
testCollectArguments()1518*795d594fSAndroid Build Coastguard Worker   public static void testCollectArguments() throws Throwable {
1519*795d594fSAndroid Build Coastguard Worker     // Test non-void filters.
1520*795d594fSAndroid Build Coastguard Worker     MethodHandle filter = MethodHandles.lookup().findStatic(
1521*795d594fSAndroid Build Coastguard Worker         Main.class, "filter",
1522*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(String.class, char.class, char.class));
1523*795d594fSAndroid Build Coastguard Worker 
1524*795d594fSAndroid Build Coastguard Worker     MethodHandle target = MethodHandles.lookup().findStatic(
1525*795d594fSAndroid Build Coastguard Worker         Main.class, "target",
1526*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class, String.class, String.class));
1527*795d594fSAndroid Build Coastguard Worker 
1528*795d594fSAndroid Build Coastguard Worker     // Filter at position 0.
1529*795d594fSAndroid Build Coastguard Worker     MethodHandle adapter = MethodHandles.collectArguments(target, 0, filter);
1530*795d594fSAndroid Build Coastguard Worker     assertEquals(57, (int) adapter.invokeExact('a', 'b', "c", "d"));
1531*795d594fSAndroid Build Coastguard Worker 
1532*795d594fSAndroid Build Coastguard Worker     // Filter at position 1.
1533*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.collectArguments(target, 1, filter);
1534*795d594fSAndroid Build Coastguard Worker     assertEquals(57, (int) adapter.invokeExact("a", 'b', 'c', "d"));
1535*795d594fSAndroid Build Coastguard Worker 
1536*795d594fSAndroid Build Coastguard Worker     // Filter at position 2.
1537*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.collectArguments(target, 2, filter);
1538*795d594fSAndroid Build Coastguard Worker     assertEquals(57, (int) adapter.invokeExact("a", "b", 'c', 'd'));
1539*795d594fSAndroid Build Coastguard Worker 
1540*795d594fSAndroid Build Coastguard Worker     // Test void filters. Note that we're passing in one more argument
1541*795d594fSAndroid Build Coastguard Worker     // than usual because the filter returns nothing - we have to invoke with
1542*795d594fSAndroid Build Coastguard Worker     // the full set of filter args and the full set of target args.
1543*795d594fSAndroid Build Coastguard Worker     filter = MethodHandles.lookup().findStatic(Main.class, "voidFilter",
1544*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(void.class, char.class, char.class));
1545*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.collectArguments(target, 0, filter);
1546*795d594fSAndroid Build Coastguard Worker     assertEquals(57, (int) adapter.invokeExact('a', 'b', "a", "b", "c"));
1547*795d594fSAndroid Build Coastguard Worker 
1548*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.collectArguments(target, 1, filter);
1549*795d594fSAndroid Build Coastguard Worker     assertEquals(57, (int) adapter.invokeExact("a", 'a', 'b', "b", "c"));
1550*795d594fSAndroid Build Coastguard Worker 
1551*795d594fSAndroid Build Coastguard Worker     // Test out a few failure cases.
1552*795d594fSAndroid Build Coastguard Worker     filter = MethodHandles.lookup().findStatic(
1553*795d594fSAndroid Build Coastguard Worker         Main.class, "filter",
1554*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(String.class, char.class, char.class));
1555*795d594fSAndroid Build Coastguard Worker 
1556*795d594fSAndroid Build Coastguard Worker     // Bogus filter position.
1557*795d594fSAndroid Build Coastguard Worker     try {
1558*795d594fSAndroid Build Coastguard Worker       adapter = MethodHandles.collectArguments(target, 3, filter);
1559*795d594fSAndroid Build Coastguard Worker       fail();
1560*795d594fSAndroid Build Coastguard Worker     } catch (IndexOutOfBoundsException | IllegalArgumentException expected) {
1561*795d594fSAndroid Build Coastguard Worker     }
1562*795d594fSAndroid Build Coastguard Worker 
1563*795d594fSAndroid Build Coastguard Worker     // Mismatch in filter return type.
1564*795d594fSAndroid Build Coastguard Worker     filter = MethodHandles.lookup().findStatic(
1565*795d594fSAndroid Build Coastguard Worker         Main.class, "badFilter",
1566*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(char.class, char.class, char.class));
1567*795d594fSAndroid Build Coastguard Worker     try {
1568*795d594fSAndroid Build Coastguard Worker       adapter = MethodHandles.collectArguments(target, 0, filter);
1569*795d594fSAndroid Build Coastguard Worker       fail();
1570*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1571*795d594fSAndroid Build Coastguard Worker     }
1572*795d594fSAndroid Build Coastguard Worker   }
1573*795d594fSAndroid Build Coastguard Worker 
insertReceiver(String a, int b, Integer c, String d)1574*795d594fSAndroid Build Coastguard Worker   static int insertReceiver(String a, int b, Integer c, String d) {
1575*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + ", b:" + b + ", c:" + c + ", d:" + d);
1576*795d594fSAndroid Build Coastguard Worker     return 73;
1577*795d594fSAndroid Build Coastguard Worker   }
1578*795d594fSAndroid Build Coastguard Worker 
testInsertArguments()1579*795d594fSAndroid Build Coastguard Worker   public static void testInsertArguments() throws Throwable {
1580*795d594fSAndroid Build Coastguard Worker     MethodHandle target = MethodHandles.lookup().findStatic(
1581*795d594fSAndroid Build Coastguard Worker         Main.class, "insertReceiver",
1582*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class,
1583*795d594fSAndroid Build Coastguard Worker           String.class, int.class, Integer.class, String.class));
1584*795d594fSAndroid Build Coastguard Worker 
1585*795d594fSAndroid Build Coastguard Worker     // Basic single element array inserted at position 0.
1586*795d594fSAndroid Build Coastguard Worker     MethodHandle adapter = MethodHandles.insertArguments(
1587*795d594fSAndroid Build Coastguard Worker         target, 0, new Object[] { "foo" });
1588*795d594fSAndroid Build Coastguard Worker     assertEquals(73, (int) adapter.invokeExact(45, Integer.valueOf(56), "bar"));
1589*795d594fSAndroid Build Coastguard Worker 
1590*795d594fSAndroid Build Coastguard Worker     // Exercise unboxing.
1591*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.insertArguments(
1592*795d594fSAndroid Build Coastguard Worker         target, 1, new Object[] { Integer.valueOf(56), 57 });
1593*795d594fSAndroid Build Coastguard Worker     assertEquals(73, (int) adapter.invokeExact("foo", "bar"));
1594*795d594fSAndroid Build Coastguard Worker 
1595*795d594fSAndroid Build Coastguard Worker     // Exercise a widening conversion.
1596*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.insertArguments(
1597*795d594fSAndroid Build Coastguard Worker         target, 1, new Object[] { (short) 56, Integer.valueOf(57) });
1598*795d594fSAndroid Build Coastguard Worker     assertEquals(73, (int) adapter.invokeExact("foo", "bar"));
1599*795d594fSAndroid Build Coastguard Worker 
1600*795d594fSAndroid Build Coastguard Worker     // Insert an argument at the last position.
1601*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.insertArguments(
1602*795d594fSAndroid Build Coastguard Worker         target, 3, new Object[] { "bar" });
1603*795d594fSAndroid Build Coastguard Worker     assertEquals(73, (int) adapter.invokeExact("foo", 45, Integer.valueOf(46)));
1604*795d594fSAndroid Build Coastguard Worker 
1605*795d594fSAndroid Build Coastguard Worker     // Exercise a few error cases.
1606*795d594fSAndroid Build Coastguard Worker 
1607*795d594fSAndroid Build Coastguard Worker     // A reference type that can't be cast to another reference type.
1608*795d594fSAndroid Build Coastguard Worker     try {
1609*795d594fSAndroid Build Coastguard Worker       MethodHandles.insertArguments(target, 3, new Object[] { new Object() });
1610*795d594fSAndroid Build Coastguard Worker       fail();
1611*795d594fSAndroid Build Coastguard Worker     } catch (ClassCastException expected) {
1612*795d594fSAndroid Build Coastguard Worker     }
1613*795d594fSAndroid Build Coastguard Worker 
1614*795d594fSAndroid Build Coastguard Worker     // A boxed type that can't be unboxed correctly.
1615*795d594fSAndroid Build Coastguard Worker     try {
1616*795d594fSAndroid Build Coastguard Worker       MethodHandles.insertArguments(target, 1, new Object[] { Long.valueOf(56) });
1617*795d594fSAndroid Build Coastguard Worker       fail();
1618*795d594fSAndroid Build Coastguard Worker     } catch (ClassCastException expected) {
1619*795d594fSAndroid Build Coastguard Worker     }
1620*795d594fSAndroid Build Coastguard Worker   }
1621*795d594fSAndroid Build Coastguard Worker 
foldFilter(char a, char b)1622*795d594fSAndroid Build Coastguard Worker   public static String foldFilter(char a, char b) {
1623*795d594fSAndroid Build Coastguard Worker     return String.valueOf(a) + "+" + b;
1624*795d594fSAndroid Build Coastguard Worker   }
1625*795d594fSAndroid Build Coastguard Worker 
voidFoldFilter(String e, char a, char b)1626*795d594fSAndroid Build Coastguard Worker   public static void voidFoldFilter(String e, char a, char b) {
1627*795d594fSAndroid Build Coastguard Worker     System.out.println(String.valueOf(a) + "+" + b);
1628*795d594fSAndroid Build Coastguard Worker   }
1629*795d594fSAndroid Build Coastguard Worker 
foldTarget(String a, char b, char c, String d)1630*795d594fSAndroid Build Coastguard Worker   public static int foldTarget(String a, char b, char c, String d) {
1631*795d594fSAndroid Build Coastguard Worker     System.out.println("a: " + a + " ,b:" + b + " ,c:" + c + " ,d:" + d);
1632*795d594fSAndroid Build Coastguard Worker     return 89;
1633*795d594fSAndroid Build Coastguard Worker   }
1634*795d594fSAndroid Build Coastguard Worker 
mismatchedVoidFilter(Integer a)1635*795d594fSAndroid Build Coastguard Worker   public static void mismatchedVoidFilter(Integer a) {
1636*795d594fSAndroid Build Coastguard Worker   }
1637*795d594fSAndroid Build Coastguard Worker 
mismatchedNonVoidFilter(char a, char b)1638*795d594fSAndroid Build Coastguard Worker   public static Integer mismatchedNonVoidFilter(char a, char b) {
1639*795d594fSAndroid Build Coastguard Worker     return null;
1640*795d594fSAndroid Build Coastguard Worker   }
1641*795d594fSAndroid Build Coastguard Worker 
testFoldArguments()1642*795d594fSAndroid Build Coastguard Worker   public static void testFoldArguments() throws Throwable {
1643*795d594fSAndroid Build Coastguard Worker     // Test non-void filters.
1644*795d594fSAndroid Build Coastguard Worker     MethodHandle filter = MethodHandles.lookup().findStatic(
1645*795d594fSAndroid Build Coastguard Worker         Main.class, "foldFilter",
1646*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(String.class, char.class, char.class));
1647*795d594fSAndroid Build Coastguard Worker 
1648*795d594fSAndroid Build Coastguard Worker     MethodHandle target = MethodHandles.lookup().findStatic(
1649*795d594fSAndroid Build Coastguard Worker         Main.class, "foldTarget",
1650*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(int.class, String.class,
1651*795d594fSAndroid Build Coastguard Worker           char.class, char.class, String.class));
1652*795d594fSAndroid Build Coastguard Worker 
1653*795d594fSAndroid Build Coastguard Worker     // Folder with a non-void type.
1654*795d594fSAndroid Build Coastguard Worker     MethodHandle adapter = MethodHandles.foldArguments(target, filter);
1655*795d594fSAndroid Build Coastguard Worker     assertEquals(89, (int) adapter.invokeExact('c', 'd', "e"));
1656*795d594fSAndroid Build Coastguard Worker 
1657*795d594fSAndroid Build Coastguard Worker     // Folder with a void type.
1658*795d594fSAndroid Build Coastguard Worker     filter = MethodHandles.lookup().findStatic(
1659*795d594fSAndroid Build Coastguard Worker         Main.class, "voidFoldFilter",
1660*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(void.class, String.class, char.class, char.class));
1661*795d594fSAndroid Build Coastguard Worker     adapter = MethodHandles.foldArguments(target, filter);
1662*795d594fSAndroid Build Coastguard Worker     assertEquals(89, (int) adapter.invokeExact("a", 'c', 'd', "e"));
1663*795d594fSAndroid Build Coastguard Worker 
1664*795d594fSAndroid Build Coastguard Worker     // Test a few erroneous cases.
1665*795d594fSAndroid Build Coastguard Worker 
1666*795d594fSAndroid Build Coastguard Worker     filter = MethodHandles.lookup().findStatic(
1667*795d594fSAndroid Build Coastguard Worker         Main.class, "mismatchedVoidFilter",
1668*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(void.class, Integer.class));
1669*795d594fSAndroid Build Coastguard Worker     try {
1670*795d594fSAndroid Build Coastguard Worker       adapter = MethodHandles.foldArguments(target, filter);
1671*795d594fSAndroid Build Coastguard Worker       fail();
1672*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1673*795d594fSAndroid Build Coastguard Worker     }
1674*795d594fSAndroid Build Coastguard Worker 
1675*795d594fSAndroid Build Coastguard Worker     filter = MethodHandles.lookup().findStatic(
1676*795d594fSAndroid Build Coastguard Worker         Main.class, "mismatchedNonVoidFilter",
1677*795d594fSAndroid Build Coastguard Worker         MethodType.methodType(Integer.class, char.class, char.class));
1678*795d594fSAndroid Build Coastguard Worker     try {
1679*795d594fSAndroid Build Coastguard Worker       adapter = MethodHandles.foldArguments(target, filter);
1680*795d594fSAndroid Build Coastguard Worker       fail();
1681*795d594fSAndroid Build Coastguard Worker     } catch (IllegalArgumentException expected) {
1682*795d594fSAndroid Build Coastguard Worker     }
1683*795d594fSAndroid Build Coastguard Worker   }
1684*795d594fSAndroid Build Coastguard Worker 
fail()1685*795d594fSAndroid Build Coastguard Worker   public static void fail() {
1686*795d594fSAndroid Build Coastguard Worker     System.out.println("FAIL");
1687*795d594fSAndroid Build Coastguard Worker     Thread.dumpStack();
1688*795d594fSAndroid Build Coastguard Worker   }
1689*795d594fSAndroid Build Coastguard Worker 
fail(String message)1690*795d594fSAndroid Build Coastguard Worker   public static void fail(String message) {
1691*795d594fSAndroid Build Coastguard Worker     System.out.println("fail: " + message);
1692*795d594fSAndroid Build Coastguard Worker     Thread.dumpStack();
1693*795d594fSAndroid Build Coastguard Worker   }
1694*795d594fSAndroid Build Coastguard Worker 
assertEquals(int i1, int i2)1695*795d594fSAndroid Build Coastguard Worker   public static void assertEquals(int i1, int i2) {
1696*795d594fSAndroid Build Coastguard Worker     if (i1 != i2) throw new AssertionError("Expected: " + i1 + " was " + i2);
1697*795d594fSAndroid Build Coastguard Worker   }
1698*795d594fSAndroid Build Coastguard Worker 
assertEquals(String s1, String s2)1699*795d594fSAndroid Build Coastguard Worker   public static void assertEquals(String s1, String s2) {
1700*795d594fSAndroid Build Coastguard Worker     if (s1 == s2) {
1701*795d594fSAndroid Build Coastguard Worker       return;
1702*795d594fSAndroid Build Coastguard Worker     }
1703*795d594fSAndroid Build Coastguard Worker 
1704*795d594fSAndroid Build Coastguard Worker     if (s1 != null && s2 != null && s1.equals(s2)) {
1705*795d594fSAndroid Build Coastguard Worker       return;
1706*795d594fSAndroid Build Coastguard Worker     }
1707*795d594fSAndroid Build Coastguard Worker 
1708*795d594fSAndroid Build Coastguard Worker     throw new AssertionError("assertEquals s1: " + s1 + ", s2: " + s2);
1709*795d594fSAndroid Build Coastguard Worker   }
1710*795d594fSAndroid Build Coastguard Worker }
1711