• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package libcore.java.lang.invoke;
18 
19 import java.lang.invoke.MethodHandle;
20 import java.lang.invoke.MethodHandles;
21 import java.lang.invoke.WrongMethodTypeException;
22 
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26 
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 import org.junit.runners.JUnit4;
30 
31 @RunWith(JUnit4.class)
32 public class MethodHandleAccessorsTest {
33     public static class ValueHolder {
34         public boolean m_z = false;
35         public byte m_b = 0;
36         public char m_c = 'a';
37         public short m_s = 0;
38         public int m_i = 0;
39         public float m_f = 0.0f;
40         public double m_d = 0.0;
41         public long m_j = 0;
42         public String m_l = "a";
43 
44         public volatile boolean m_v_z = false;
45         public volatile byte m_v_b = 0;
46         public volatile char m_v_c = 'a';
47         public volatile short m_v_s = 0;
48         public volatile int m_v_i = 0;
49         public volatile float m_v_f = 0.0f;
50         public volatile double m_v_d = 0.0;
51         public volatile long m_v_j = 0;
52         public volatile String m_v_l = "a";
53 
54         public static boolean s_z;
55         public static byte s_b;
56         public static char s_c;
57         public static short s_s;
58         public static int s_i;
59         public static float s_f;
60         public static double s_d;
61         public static long s_j;
62         public static String s_l;
63 
64         public static boolean s_v_z;
65         public static byte s_v_b;
66         public static char s_v_c;
67         public static short s_v_s;
68         public static int s_v_i;
69         public static float s_v_f;
70         public static double s_v_d;
71         public static long s_v_j;
72         public static String s_v_l;
73 
74 
75         public final int m_fi = 0xa5a5a5a5;
76         public static final int s_fi = 0x5a5a5a5a;
77     }
78 
79     private static enum PrimitiveType {
80         Boolean,
81         Byte,
82         Char,
83         Short,
84         Int,
85         Long,
86         Float,
87         Double,
88         String,
89     }
90 
91     private static enum AccessorType {
92         IPUT,
93         SPUT,
94         IGET,
95         SGET,
96     }
97 
setByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)98     static void setByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)
99             throws Throwable {
100         boolean exceptionThrown = false;
101         try {
102             if (v == null) {
103                 m.invokeExact(value);
104             }
105             else {
106                 m.invokeExact(v, value);
107             }
108         }
109         catch (WrongMethodTypeException e) {
110             exceptionThrown = true;
111         }
112         assertEquals(exceptionThrown, expectFailure);
113     }
114 
setByte(MethodHandle m, byte value, boolean expectFailure)115     static void setByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable {
116         setByte(m, null, value, expectFailure);
117     }
118 
getByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)119     static void getByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)
120             throws Throwable {
121         boolean exceptionThrown = false;
122         try {
123             final byte got;
124             if (v == null) {
125                 got = (byte)m.invokeExact();
126             } else {
127                 got = (byte)m.invokeExact(v);
128             }
129             assertTrue(got == value);
130         }
131         catch (WrongMethodTypeException e) {
132             exceptionThrown = true;
133         }
134         assertEquals(exceptionThrown, expectFailure);
135     }
136 
getByte(MethodHandle m, byte value, boolean expectFailure)137     static void getByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable {
138         getByte(m, null, value, expectFailure);
139     }
140 
setChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)141     static void setChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)
142             throws Throwable {
143         boolean exceptionThrown = false;
144         try {
145             if (v == null) {
146                 m.invokeExact(value);
147             }
148             else {
149                 m.invokeExact(v, value);
150             }
151         }
152         catch (WrongMethodTypeException e) {
153             exceptionThrown = true;
154         }
155         assertEquals(exceptionThrown, expectFailure);
156     }
157 
setChar(MethodHandle m, char value, boolean expectFailure)158     static void setChar(MethodHandle m, char value, boolean expectFailure) throws Throwable {
159         setChar(m, null, value, expectFailure);
160     }
161 
getChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)162     static void getChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)
163             throws Throwable {
164         boolean exceptionThrown = false;
165         try {
166             final char got;
167             if (v == null) {
168                 got = (char)m.invokeExact();
169             } else {
170                 got = (char)m.invokeExact(v);
171             }
172             assertTrue(got == value);
173         }
174         catch (WrongMethodTypeException e) {
175             exceptionThrown = true;
176         }
177         assertEquals(exceptionThrown, expectFailure);
178     }
179 
getChar(MethodHandle m, char value, boolean expectFailure)180     static void getChar(MethodHandle m, char value, boolean expectFailure) throws Throwable {
181         getChar(m, null, value, expectFailure);
182     }
183 
setShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)184     static void setShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)
185             throws Throwable {
186         boolean exceptionThrown = false;
187         try {
188             if (v == null) {
189                 m.invokeExact(value);
190             }
191             else {
192                 m.invokeExact(v, value);
193             }
194         }
195         catch (WrongMethodTypeException e) {
196             exceptionThrown = true;
197         }
198         assertEquals(exceptionThrown, expectFailure);
199     }
200 
setShort(MethodHandle m, short value, boolean expectFailure)201     static void setShort(MethodHandle m, short value, boolean expectFailure) throws Throwable {
202         setShort(m, null, value, expectFailure);
203     }
204 
getShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)205     static void getShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)
206             throws Throwable {
207         boolean exceptionThrown = false;
208         try {
209             final short got = (v == null) ? (short)m.invokeExact() : (short)m.invokeExact(v);
210             assertTrue(got == value);
211         }
212         catch (WrongMethodTypeException e) {
213             exceptionThrown = true;
214         }
215         assertEquals(exceptionThrown, expectFailure);
216     }
217 
getShort(MethodHandle m, short value, boolean expectFailure)218     static void getShort(MethodHandle m, short value, boolean expectFailure) throws Throwable {
219         getShort(m, null, value, expectFailure);
220     }
221 
setInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)222     static void setInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)
223             throws Throwable {
224         boolean exceptionThrown = false;
225         try {
226             if (v == null) {
227                 m.invokeExact(value);
228             }
229             else {
230                 m.invokeExact(v, value);
231             }
232         }
233         catch (WrongMethodTypeException e) {
234             exceptionThrown = true;
235         }
236         assertEquals(exceptionThrown, expectFailure);
237     }
238 
setInt(MethodHandle m, int value, boolean expectFailure)239     static void setInt(MethodHandle m, int value, boolean expectFailure) throws Throwable {
240         setInt(m, null, value, expectFailure);
241     }
242 
getInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)243     static void getInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)
244             throws Throwable {
245         boolean exceptionThrown = false;
246         try {
247             final int got = (v == null) ? (int)m.invokeExact() : (int)m.invokeExact(v);
248             assertTrue(got == value);
249         }
250         catch (WrongMethodTypeException e) {
251             exceptionThrown = true;
252         }
253         assertEquals(exceptionThrown, expectFailure);
254     }
255 
getInt(MethodHandle m, int value, boolean expectFailure)256     static void getInt(MethodHandle m, int value, boolean expectFailure) throws Throwable {
257         getInt(m, null, value, expectFailure);
258     }
259 
setLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)260     static void setLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)
261             throws Throwable {
262         boolean exceptionThrown = false;
263         try {
264             if (v == null) {
265                 m.invokeExact(value);
266             }
267             else {
268                 m.invokeExact(v, value);
269             }
270         }
271         catch (WrongMethodTypeException e) {
272             exceptionThrown = true;
273         }
274         assertEquals(exceptionThrown, expectFailure);
275     }
276 
setLong(MethodHandle m, long value, boolean expectFailure)277     static void setLong(MethodHandle m, long value, boolean expectFailure) throws Throwable {
278         setLong(m, null, value, expectFailure);
279     }
280 
getLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)281     static void getLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)
282             throws Throwable {
283         boolean exceptionThrown = false;
284         try {
285             final long got = (v == null) ? (long)m.invokeExact() : (long)m.invokeExact(v);
286             assertTrue(got == value);
287         }
288         catch (WrongMethodTypeException e) {
289             exceptionThrown = true;
290         }
291         assertEquals(exceptionThrown, expectFailure);
292     }
293 
getLong(MethodHandle m, long value, boolean expectFailure)294     static void getLong(MethodHandle m, long value, boolean expectFailure) throws Throwable {
295         getLong(m, null, value, expectFailure);
296     }
297 
setFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)298     static void setFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)
299             throws Throwable {
300         boolean exceptionThrown = false;
301         try {
302             if (v == null) {
303                 m.invokeExact(value);
304             }
305             else {
306                 m.invokeExact(v, value);
307             }
308         }
309         catch (WrongMethodTypeException e) {
310             exceptionThrown = true;
311         }
312         assertEquals(exceptionThrown, expectFailure);
313     }
314 
setFloat(MethodHandle m, float value, boolean expectFailure)315     static void setFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable {
316         setFloat(m, null, value, expectFailure);
317     }
318 
getFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)319     static void getFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)
320             throws Throwable {
321         boolean exceptionThrown = false;
322         try {
323             final float got = (v == null) ? (float)m.invokeExact() : (float)m.invokeExact(v);
324             assertTrue(got == value);
325         }
326         catch (WrongMethodTypeException e) {
327             exceptionThrown = true;
328         }
329         assertEquals(exceptionThrown, expectFailure);
330     }
331 
getFloat(MethodHandle m, float value, boolean expectFailure)332     static void getFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable {
333         getFloat(m, null, value, expectFailure);
334     }
335 
setDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)336     static void setDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)
337             throws Throwable {
338         boolean exceptionThrown = false;
339         try {
340             if (v == null) {
341                 m.invokeExact(value);
342             }
343             else {
344                 m.invokeExact(v, value);
345             }
346         }
347         catch (WrongMethodTypeException e) {
348             exceptionThrown = true;
349         }
350         assertEquals(exceptionThrown, expectFailure);
351     }
352 
setDouble(MethodHandle m, double value, boolean expectFailure)353     static void setDouble(MethodHandle m, double value, boolean expectFailure)
354             throws Throwable {
355         setDouble(m, null, value, expectFailure);
356     }
357 
getDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)358     static void getDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)
359             throws Throwable {
360         boolean exceptionThrown = false;
361         try {
362             final double got = (v == null) ? (double)m.invokeExact() : (double)m.invokeExact(v);
363             assertTrue(got == value);
364         }
365         catch (WrongMethodTypeException e) {
366             exceptionThrown = true;
367         }
368         assertEquals(exceptionThrown, expectFailure);
369     }
370 
getDouble(MethodHandle m, double value, boolean expectFailure)371     static void getDouble(MethodHandle m, double value, boolean expectFailure)
372             throws Throwable {
373         getDouble(m, null, value, expectFailure);
374     }
375 
setString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)376     static void setString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)
377             throws Throwable {
378         boolean exceptionThrown = false;
379         try {
380             if (v == null) {
381                 m.invokeExact(value);
382             }
383             else {
384                 m.invokeExact(v, value);
385             }
386         }
387         catch (WrongMethodTypeException e) {
388             exceptionThrown = true;
389         }
390         assertEquals(exceptionThrown, expectFailure);
391     }
392 
setString(MethodHandle m, String value, boolean expectFailure)393     static void setString(MethodHandle m, String value, boolean expectFailure)
394             throws Throwable {
395         setString(m, null, value, expectFailure);
396     }
397 
getString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)398     static void getString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)
399             throws Throwable {
400         boolean exceptionThrown = false;
401         try {
402             final String got = (v == null) ? (String)m.invokeExact() : (String)m.invokeExact(v);
403             assertTrue(got.equals(value));
404         }
405         catch (WrongMethodTypeException e) {
406             exceptionThrown = true;
407         }
408         assertEquals(exceptionThrown, expectFailure);
409     }
410 
getString(MethodHandle m, String value, boolean expectFailure)411     static void getString(MethodHandle m, String value, boolean expectFailure)
412             throws Throwable {
413         getString(m, null, value, expectFailure);
414     }
415 
setBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)416     static void setBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)
417             throws Throwable {
418         boolean exceptionThrown = false;
419         try {
420             if (v == null) {
421                 m.invokeExact(value);
422             }
423             else {
424                 m.invokeExact(v, value);
425             }
426         }
427         catch (WrongMethodTypeException e) {
428             exceptionThrown = true;
429         }
430         assertEquals(exceptionThrown, expectFailure);
431     }
432 
setBoolean(MethodHandle m, boolean value, boolean expectFailure)433     static void setBoolean(MethodHandle m, boolean value, boolean expectFailure)
434             throws Throwable {
435         setBoolean(m, null, value, expectFailure);
436     }
437 
getBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)438     static void getBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)
439             throws Throwable {
440         boolean exceptionThrown = false;
441         try {
442             final boolean got =
443                     (v == null) ? (boolean)m.invokeExact() : (boolean)m.invokeExact(v);
444             assertTrue(got == value);
445         }
446         catch (WrongMethodTypeException e) {
447             exceptionThrown = true;
448         }
449         assertEquals(exceptionThrown, expectFailure);
450     }
451 
getBoolean(MethodHandle m, boolean value, boolean expectFailure)452     static void getBoolean(MethodHandle m, boolean value, boolean expectFailure)
453             throws Throwable {
454         getBoolean(m, null, value, expectFailure);
455     }
456 
resultFor(PrimitiveType actualType, PrimitiveType expectedType, AccessorType actualAccessor, AccessorType expectedAccessor)457     static boolean resultFor(PrimitiveType actualType, PrimitiveType expectedType,
458                              AccessorType actualAccessor,
459                              AccessorType expectedAccessor) {
460         return (actualType != expectedType) || (actualAccessor != expectedAccessor);
461     }
462 
tryAccessor(MethodHandle methodHandle, ValueHolder valueHolder, PrimitiveType primitive, Object value, AccessorType accessor)463     static void tryAccessor(MethodHandle methodHandle,
464                             ValueHolder valueHolder,
465                             PrimitiveType primitive,
466                             Object value,
467                             AccessorType accessor) throws Throwable {
468         boolean booleanValue =
469                 value instanceof Boolean ? ((Boolean)value).booleanValue() : false;
470         setBoolean(methodHandle, valueHolder, booleanValue,
471                 resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.IPUT));
472         setBoolean(methodHandle, booleanValue,
473                 resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.SPUT));
474         getBoolean(methodHandle, valueHolder, booleanValue,
475                 resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.IGET));
476         getBoolean(methodHandle, booleanValue,
477                 resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.SGET));
478 
479         byte byteValue = value instanceof Byte ? ((Byte)value).byteValue() : (byte)0;
480         setByte(methodHandle, valueHolder, byteValue,
481                 resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.IPUT));
482         setByte(methodHandle, byteValue,
483                 resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.SPUT));
484         getByte(methodHandle, valueHolder, byteValue,
485                 resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.IGET));
486         getByte(methodHandle, byteValue,
487                 resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.SGET));
488 
489         char charValue = value instanceof Character ? ((Character)value).charValue() : 'z';
490         setChar(methodHandle, valueHolder, charValue,
491                 resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.IPUT));
492         setChar(methodHandle, charValue,
493                 resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.SPUT));
494         getChar(methodHandle, valueHolder, charValue,
495                 resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.IGET));
496         getChar(methodHandle, charValue,
497                 resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.SGET));
498 
499         short shortValue = value instanceof Short ? ((Short)value).shortValue() : (short)0;
500         setShort(methodHandle, valueHolder, shortValue,
501                 resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.IPUT));
502         setShort(methodHandle, shortValue,
503                 resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.SPUT));
504         getShort(methodHandle, valueHolder, shortValue,
505                 resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.IGET));
506         getShort(methodHandle, shortValue,
507                 resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.SGET));
508 
509         int intValue = value instanceof Integer ? ((Integer)value).intValue() : -1;
510         setInt(methodHandle, valueHolder, intValue,
511                 resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.IPUT));
512         setInt(methodHandle, intValue,
513                 resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.SPUT));
514         getInt(methodHandle, valueHolder, intValue,
515                 resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.IGET));
516         getInt(methodHandle, intValue,
517                 resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.SGET));
518 
519         long longValue = value instanceof Long ? ((Long)value).longValue() : (long)-1;
520         setLong(methodHandle, valueHolder, longValue,
521                 resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.IPUT));
522         setLong(methodHandle, longValue,
523                 resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.SPUT));
524         getLong(methodHandle, valueHolder, longValue,
525                 resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.IGET));
526         getLong(methodHandle, longValue,
527                 resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.SGET));
528 
529         float floatValue = value instanceof Float ? ((Float)value).floatValue() : -1.0f;
530         setFloat(methodHandle, valueHolder, floatValue,
531                 resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.IPUT));
532         setFloat(methodHandle, floatValue,
533                 resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.SPUT));
534         getFloat(methodHandle, valueHolder, floatValue,
535                 resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.IGET));
536         getFloat(methodHandle, floatValue,
537                 resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.SGET));
538 
539         double doubleValue = value instanceof Double ? ((Double)value).doubleValue() : -1.0;
540         setDouble(methodHandle, valueHolder, doubleValue,
541                 resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.IPUT));
542         setDouble(methodHandle, doubleValue,
543                 resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.SPUT));
544         getDouble(methodHandle, valueHolder, doubleValue,
545                 resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.IGET));
546         getDouble(methodHandle, doubleValue,
547                 resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.SGET));
548 
549         String stringValue = value instanceof String ? ((String) value) : "No Spock, no";
550         setString(methodHandle, valueHolder, stringValue,
551                 resultFor(primitive, PrimitiveType.String, accessor, AccessorType.IPUT));
552         setString(methodHandle, stringValue,
553                 resultFor(primitive, PrimitiveType.String, accessor, AccessorType.SPUT));
554         getString(methodHandle, valueHolder, stringValue,
555                 resultFor(primitive, PrimitiveType.String, accessor, AccessorType.IGET));
556         getString(methodHandle, stringValue,
557                 resultFor(primitive, PrimitiveType.String, accessor, AccessorType.SGET));
558     }
559 
560     @Test
testBooleanSettersAndGetters()561     public void testBooleanSettersAndGetters() throws Throwable {
562         ValueHolder valueHolder = new ValueHolder();
563         MethodHandles.Lookup lookup = MethodHandles.lookup();
564 
565         boolean[] booleans = {false, true, false};
566         for (boolean b : booleans) {
567             Boolean boxed = Boolean.valueOf(b);
568 
569             tryAccessor(lookup.findSetter(ValueHolder.class, "m_z", boolean.class),
570                 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.IPUT);
571             tryAccessor(lookup.findGetter(ValueHolder.class, "m_z", boolean.class),
572                 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.IGET);
573             assertTrue(valueHolder.m_z == b);
574 
575             tryAccessor(lookup.findSetter(ValueHolder.class, "m_v_z", boolean.class),
576                 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.IPUT);
577             tryAccessor(lookup.findGetter(ValueHolder.class, "m_v_z", boolean.class),
578                 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.IGET);
579             assertTrue(valueHolder.m_v_z == b);
580 
581             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_z", boolean.class),
582                 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.SPUT);
583             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_z", boolean.class),
584                 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.SGET);
585             assertTrue(ValueHolder.s_z == b);
586 
587             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_v_z", boolean.class),
588                 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.SPUT);
589             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_v_z", boolean.class),
590                 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.SGET);
591             assertTrue(ValueHolder.s_v_z == b);
592         }
593     }
594 
595     @Test
testByteSettersAndGetters()596     public void testByteSettersAndGetters() throws Throwable {
597         ValueHolder valueHolder = new ValueHolder();
598         MethodHandles.Lookup lookup = MethodHandles.lookup();
599 
600         byte[] bytes = {(byte) 0x73, (byte) 0xfe};
601         for (byte b : bytes) {
602             Byte boxed = Byte.valueOf(b);
603 
604             tryAccessor(lookup.findSetter(ValueHolder.class, "m_b", byte.class),
605                 valueHolder, PrimitiveType.Byte, boxed, AccessorType.IPUT);
606             tryAccessor(lookup.findGetter(ValueHolder.class, "m_b", byte.class),
607                 valueHolder, PrimitiveType.Byte, boxed, AccessorType.IGET);
608             assertTrue(valueHolder.m_b == b);
609 
610             tryAccessor(lookup.findSetter(ValueHolder.class, "m_v_b", byte.class),
611                 valueHolder, PrimitiveType.Byte, boxed, AccessorType.IPUT);
612             tryAccessor(lookup.findGetter(ValueHolder.class, "m_v_b", byte.class),
613                 valueHolder, PrimitiveType.Byte, boxed, AccessorType.IGET);
614             assertTrue(valueHolder.m_v_b == b);
615 
616             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_b", byte.class),
617                 valueHolder, PrimitiveType.Byte, boxed, AccessorType.SPUT);
618             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_b", byte.class),
619                 valueHolder, PrimitiveType.Byte, boxed, AccessorType.SGET);
620             assertTrue(ValueHolder.s_b == b);
621 
622             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_v_b", byte.class),
623                 valueHolder, PrimitiveType.Byte, boxed, AccessorType.SPUT);
624             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_v_b", byte.class),
625                 valueHolder, PrimitiveType.Byte, boxed, AccessorType.SGET);
626             assertTrue(ValueHolder.s_v_b == b);        }
627     }
628 
629     @Test
testCharSettersAndGetters()630     public void testCharSettersAndGetters() throws Throwable {
631         ValueHolder valueHolder = new ValueHolder();
632         MethodHandles.Lookup lookup = MethodHandles.lookup();
633 
634         char[] chars = {'a', 'b', 'c'};
635         for (char c : chars) {
636             Character boxed = Character.valueOf(c);
637 
638             tryAccessor(lookup.findSetter(ValueHolder.class, "m_c", char.class),
639                 valueHolder, PrimitiveType.Char, boxed, AccessorType.IPUT);
640             tryAccessor(lookup.findGetter(ValueHolder.class, "m_c", char.class),
641                 valueHolder, PrimitiveType.Char, boxed, AccessorType.IGET);
642             assertTrue(valueHolder.m_c == c);
643 
644             tryAccessor(lookup.findSetter(ValueHolder.class, "m_v_c", char.class),
645                 valueHolder, PrimitiveType.Char, boxed, AccessorType.IPUT);
646             tryAccessor(lookup.findGetter(ValueHolder.class, "m_v_c", char.class),
647                 valueHolder, PrimitiveType.Char, boxed, AccessorType.IGET);
648             assertTrue(valueHolder.m_v_c == c);
649 
650             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_c", char.class),
651                 valueHolder, PrimitiveType.Char, boxed, AccessorType.SPUT);
652             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_c", char.class),
653                 valueHolder, PrimitiveType.Char, boxed, AccessorType.SGET);
654             assertTrue(ValueHolder.s_c == c);
655 
656             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_v_c", char.class),
657                 valueHolder, PrimitiveType.Char, boxed, AccessorType.SPUT);
658             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_v_c", char.class),
659                 valueHolder, PrimitiveType.Char, boxed, AccessorType.SGET);
660             assertTrue(ValueHolder.s_v_c == c);
661         }
662     }
663 
664     @Test
testShortSettersAndGetters()665     public void testShortSettersAndGetters() throws Throwable {
666         ValueHolder valueHolder = new ValueHolder();
667         MethodHandles.Lookup lookup = MethodHandles.lookup();
668 
669         short[] shorts = {(short) 0x1234, (short) 0x4321};
670         for (short s : shorts) {
671             Short boxed = Short.valueOf(s);
672 
673             tryAccessor(lookup.findSetter(ValueHolder.class, "m_s", short.class),
674                 valueHolder, PrimitiveType.Short, boxed, AccessorType.IPUT);
675             tryAccessor(lookup.findGetter(ValueHolder.class, "m_s", short.class),
676                 valueHolder, PrimitiveType.Short, boxed, AccessorType.IGET);
677             assertTrue(valueHolder.m_s == s);
678 
679             tryAccessor(lookup.findSetter(ValueHolder.class, "m_v_s", short.class),
680                 valueHolder, PrimitiveType.Short, boxed, AccessorType.IPUT);
681             tryAccessor(lookup.findGetter(ValueHolder.class, "m_v_s", short.class),
682                 valueHolder, PrimitiveType.Short, boxed, AccessorType.IGET);
683             assertTrue(valueHolder.m_v_s == s);
684 
685             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_s", short.class),
686                 valueHolder, PrimitiveType.Short, boxed, AccessorType.SPUT);
687             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_s", short.class),
688                 valueHolder, PrimitiveType.Short, boxed, AccessorType.SGET);
689             assertTrue(ValueHolder.s_s == s);
690 
691             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_v_s", short.class),
692                 valueHolder, PrimitiveType.Short, boxed, AccessorType.SPUT);
693             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_v_s", short.class),
694                 valueHolder, PrimitiveType.Short, boxed, AccessorType.SGET);
695             assertTrue(ValueHolder.s_v_s == s);
696         }
697     }
698 
699     @Test
testIntSettersAndGetters()700     public void testIntSettersAndGetters() throws Throwable {
701         ValueHolder valueHolder = new ValueHolder();
702         MethodHandles.Lookup lookup = MethodHandles.lookup();
703 
704         int[] ints = {-100000000, 10000000};
705         for (int i : ints) {
706             Integer boxed = Integer.valueOf(i);
707 
708             tryAccessor(lookup.findSetter(ValueHolder.class, "m_i", int.class),
709                 valueHolder, PrimitiveType.Int, boxed, AccessorType.IPUT);
710             tryAccessor(lookup.findGetter(ValueHolder.class, "m_i", int.class),
711                 valueHolder, PrimitiveType.Int, boxed, AccessorType.IGET);
712             assertTrue(valueHolder.m_i == i);
713 
714             tryAccessor(lookup.findSetter(ValueHolder.class, "m_v_i", int.class),
715                 valueHolder, PrimitiveType.Int, boxed, AccessorType.IPUT);
716             tryAccessor(lookup.findGetter(ValueHolder.class, "m_v_i", int.class),
717                 valueHolder, PrimitiveType.Int, boxed, AccessorType.IGET);
718             assertTrue(valueHolder.m_v_i == i);
719 
720             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_i", int.class),
721                 valueHolder, PrimitiveType.Int, boxed, AccessorType.SPUT);
722             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_i", int.class),
723                 valueHolder, PrimitiveType.Int, boxed, AccessorType.SGET);
724             assertTrue(ValueHolder.s_i == i);
725 
726             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_v_i", int.class),
727                 valueHolder, PrimitiveType.Int, boxed, AccessorType.SPUT);
728             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_v_i", int.class),
729                 valueHolder, PrimitiveType.Int, boxed, AccessorType.SGET);
730             assertTrue(ValueHolder.s_v_i == i);
731         }
732     }
733 
734     @Test
testFloatSettersAndGetters()735     public void testFloatSettersAndGetters() throws Throwable {
736         ValueHolder valueHolder = new ValueHolder();
737         MethodHandles.Lookup lookup = MethodHandles.lookup();
738 
739         float[] floats = {0.99f, -1.23e-17f};
740         for (float f : floats) {
741             Float boxed = Float.valueOf(f);
742 
743             tryAccessor(lookup.findSetter(ValueHolder.class, "m_f", float.class),
744                 valueHolder, PrimitiveType.Float, boxed, AccessorType.IPUT);
745             tryAccessor(lookup.findGetter(ValueHolder.class, "m_f", float.class),
746                 valueHolder, PrimitiveType.Float, boxed, AccessorType.IGET);
747             assertTrue(valueHolder.m_f == f);
748 
749             tryAccessor(lookup.findSetter(ValueHolder.class, "m_v_f", float.class),
750                     valueHolder, PrimitiveType.Float, boxed, AccessorType.IPUT);
751             tryAccessor(lookup.findGetter(ValueHolder.class, "m_v_f", float.class),
752                     valueHolder, PrimitiveType.Float, boxed, AccessorType.IGET);
753             assertTrue(valueHolder.m_v_f == f);
754 
755             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_f", float.class),
756                 valueHolder, PrimitiveType.Float, boxed, AccessorType.SPUT);
757             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_f", float.class),
758                 valueHolder, PrimitiveType.Float, boxed, AccessorType.SGET);
759             assertTrue(ValueHolder.s_f == f);
760 
761             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_v_f", float.class),
762                     valueHolder, PrimitiveType.Float, boxed, AccessorType.SPUT);
763             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_v_f", float.class),
764                     valueHolder, PrimitiveType.Float, boxed, AccessorType.SGET);
765             assertTrue(ValueHolder.s_v_f == f);
766         }
767     }
768 
769     @Test
testDoubleSettersAndGetters()770     public void testDoubleSettersAndGetters() throws Throwable {
771         ValueHolder valueHolder = new ValueHolder();
772         MethodHandles.Lookup lookup = MethodHandles.lookup();
773 
774         double[] doubles = {0.44444444444e37, -0.555555555e-37};
775         for (double d : doubles) {
776             Double boxed = Double.valueOf(d);
777             tryAccessor(lookup.findSetter(ValueHolder.class, "m_d", double.class),
778                 valueHolder, PrimitiveType.Double, boxed, AccessorType.IPUT);
779             tryAccessor(lookup.findGetter(ValueHolder.class, "m_d", double.class),
780                 valueHolder, PrimitiveType.Double, boxed, AccessorType.IGET);
781             assertTrue(valueHolder.m_d == d);
782 
783             tryAccessor(lookup.findSetter(ValueHolder.class, "m_v_d", double.class),
784                     valueHolder, PrimitiveType.Double, boxed, AccessorType.IPUT);
785             tryAccessor(lookup.findGetter(ValueHolder.class, "m_v_d", double.class),
786                     valueHolder, PrimitiveType.Double, boxed, AccessorType.IGET);
787             assertTrue(valueHolder.m_v_d == d);
788 
789             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_d", double.class),
790                 valueHolder, PrimitiveType.Double, boxed, AccessorType.SPUT);
791             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_d", double.class),
792                 valueHolder, PrimitiveType.Double, boxed, AccessorType.SGET);
793             assertTrue(ValueHolder.s_d == d);
794 
795             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_v_d", double.class),
796                     valueHolder, PrimitiveType.Double, boxed, AccessorType.SPUT);
797             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_v_d", double.class),
798                     valueHolder, PrimitiveType.Double, boxed, AccessorType.SGET);
799             assertTrue(ValueHolder.s_v_d == d);
800         }
801     }
802 
803     @Test
testLongSettersAndGetters()804     public void testLongSettersAndGetters() throws Throwable {
805         ValueHolder valueHolder = new ValueHolder();
806         MethodHandles.Lookup lookup = MethodHandles.lookup();
807 
808         long[] longs = {0x0123456789abcdefl, 0xfedcba9876543210l};
809         for (long j : longs) {
810             Long boxed = Long.valueOf(j);
811 
812             tryAccessor(lookup.findSetter(ValueHolder.class, "m_j", long.class),
813                 valueHolder, PrimitiveType.Long, boxed, AccessorType.IPUT);
814             tryAccessor(lookup.findGetter(ValueHolder.class, "m_j", long.class),
815                 valueHolder, PrimitiveType.Long, boxed, AccessorType.IGET);
816             assertTrue(valueHolder.m_j == j);
817 
818             tryAccessor(lookup.findSetter(ValueHolder.class, "m_v_j", long.class),
819                     valueHolder, PrimitiveType.Long, boxed, AccessorType.IPUT);
820             tryAccessor(lookup.findGetter(ValueHolder.class, "m_v_j", long.class),
821                     valueHolder, PrimitiveType.Long, boxed, AccessorType.IGET);
822             assertTrue(valueHolder.m_v_j == j);
823 
824             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_j", long.class),
825                 valueHolder, PrimitiveType.Long, boxed, AccessorType.SPUT);
826             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_j", long.class),
827                 valueHolder, PrimitiveType.Long, boxed, AccessorType.SGET);
828             assertTrue(ValueHolder.s_j == j);
829 
830             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_v_j", long.class),
831                     valueHolder, PrimitiveType.Long, boxed, AccessorType.SPUT);
832             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_v_j", long.class),
833                     valueHolder, PrimitiveType.Long, boxed, AccessorType.SGET);
834             assertTrue(ValueHolder.s_v_j == j);
835         }
836     }
837 
838     @Test
testStringSettersAndGetters()839     public void testStringSettersAndGetters() throws Throwable {
840         ValueHolder valueHolder = new ValueHolder();
841         MethodHandles.Lookup lookup = MethodHandles.lookup();
842 
843         String [] strings = { "octopus", "crab" };
844         for (String s : strings) {
845             tryAccessor(lookup.findSetter(ValueHolder.class, "m_l", String.class),
846                     valueHolder, PrimitiveType.String, s, AccessorType.IPUT);
847             tryAccessor(lookup.findGetter(ValueHolder.class, "m_l", String.class),
848                     valueHolder, PrimitiveType.String, s, AccessorType.IGET);
849             assertTrue(s.equals(valueHolder.m_l));
850 
851             tryAccessor(lookup.findSetter(ValueHolder.class, "m_v_l", String.class),
852                     valueHolder, PrimitiveType.String, s, AccessorType.IPUT);
853             tryAccessor(lookup.findGetter(ValueHolder.class, "m_v_l", String.class),
854                     valueHolder, PrimitiveType.String, s, AccessorType.IGET);
855             assertTrue(s.equals(valueHolder.m_v_l));
856 
857             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_l", String.class),
858                     valueHolder, PrimitiveType.String, s, AccessorType.SPUT);
859             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_l", String.class),
860                     valueHolder, PrimitiveType.String, s, AccessorType.SGET);
861             assertTrue(s.equals(ValueHolder.s_l));
862 
863             tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_v_l", String.class),
864                     valueHolder, PrimitiveType.String, s, AccessorType.SPUT);
865             tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_v_l", String.class),
866                     valueHolder, PrimitiveType.String, s, AccessorType.SGET);
867             assertTrue(s.equals(ValueHolder.s_v_l));
868         }
869     }
870 
871     @Test
testLookup()872     public void testLookup() throws Throwable {
873         // NB having a static field test here is essential for
874         // this test. MethodHandles need to ensure the class
875         // (ValueHolder) is initialized. This happens in the
876         // invoke-polymorphic dispatch.
877         MethodHandles.Lookup lookup = MethodHandles.lookup();
878         try {
879             MethodHandle mh = lookup.findStaticGetter(ValueHolder.class, "s_fi", int.class);
880             int initialValue = (int)mh.invokeExact();
881             System.out.println(initialValue);
882         } catch (NoSuchFieldException e) { fail(); }
883         try {
884             MethodHandle mh = lookup.findStaticSetter(ValueHolder.class, "s_i", int.class);
885             mh.invokeExact(0);
886         } catch (NoSuchFieldException e) { fail(); }
887         try {
888             lookup.findStaticGetter(ValueHolder.class, "s_fi", byte.class);
889             fail();
890         } catch (NoSuchFieldException e) {}
891         try {
892             lookup.findGetter(ValueHolder.class, "s_fi", byte.class);
893             fail();
894         } catch (NoSuchFieldException e) {}
895         try {
896             lookup.findStaticSetter(ValueHolder.class, "s_fi", int.class);
897             fail();
898         } catch (IllegalAccessException e) {}
899 
900         lookup.findGetter(ValueHolder.class, "m_fi", int.class);
901         try {
902             lookup.findGetter(ValueHolder.class, "m_fi", byte.class);
903             fail();
904         } catch (NoSuchFieldException e) {}
905         try {
906             lookup.findStaticGetter(ValueHolder.class, "m_fi", byte.class);
907             fail();
908         } catch (NoSuchFieldException e) {}
909         try {
910             lookup.findSetter(ValueHolder.class, "m_fi", int.class);
911             fail();
912         } catch (IllegalAccessException e) {}
913     }
914 
915     @Test
testStaticGetter()916     public void testStaticGetter() throws Throwable {
917         MethodHandles.Lookup lookup = MethodHandles.lookup();
918         MethodHandle h0 = lookup.findStaticGetter(ValueHolder.class, "s_fi", int.class);
919         h0.invoke();
920         Number t = (Number)h0.invoke();
921         int u = (int)h0.invoke();
922         Integer v = (Integer)h0.invoke();
923         long w = (long)h0.invoke();
924         try {
925             byte x = (byte)h0.invoke();
926             fail();
927         } catch (WrongMethodTypeException e) {}
928         try {
929             String y = (String)h0.invoke();
930             fail();
931         } catch (WrongMethodTypeException e) {}
932         try {
933             Long z = (Long)h0.invoke();
934             fail();
935         } catch (WrongMethodTypeException e) {}
936     }
937 
938     @Test
testMemberGetter()939     public void testMemberGetter() throws Throwable {
940         ValueHolder valueHolder = new ValueHolder();
941         MethodHandles.Lookup lookup = MethodHandles.lookup();
942         MethodHandle h0 = lookup.findGetter(ValueHolder.class, "m_fi", int.class);
943         h0.invoke(valueHolder);
944         Number t = (Number)h0.invoke(valueHolder);
945         int u = (int)h0.invoke(valueHolder);
946         Integer v = (Integer)h0.invoke(valueHolder);
947         long w = (long)h0.invoke(valueHolder);
948         try {
949             byte x = (byte)h0.invoke(valueHolder);
950             fail();
951         } catch (WrongMethodTypeException e) {}
952         try {
953             String y = (String)h0.invoke(valueHolder);
954             fail();
955         } catch (WrongMethodTypeException e) {}
956         try {
957             Long z = (Long)h0.invoke(valueHolder);
958             fail();
959         } catch (WrongMethodTypeException e) {}
960     }
961 
getDoubleAsNumber()962     /*package*/ static Number getDoubleAsNumber() {
963         return Double.valueOf(1.4e77);
964     }
getFloatAsNumber()965     /*package*/ static Number getFloatAsNumber() {
966         return Float.valueOf(7.77f);
967     }
getFloatAsObject()968     /*package*/ static Object getFloatAsObject() {
969         return Float.valueOf(-7.77f);
970     }
971 
972     @Test
testMemberSetter()973     public void testMemberSetter() throws Throwable {
974         ValueHolder valueHolder = new ValueHolder();
975         MethodHandles.Lookup lookup = MethodHandles.lookup();
976         MethodHandle h0 = lookup.findSetter(ValueHolder.class, "m_f", float.class);
977         h0.invoke(valueHolder, 0.22f);
978         h0.invoke(valueHolder, Float.valueOf(1.11f));
979         Number floatNumber = getFloatAsNumber();
980         h0.invoke(valueHolder, floatNumber);
981         assertTrue(valueHolder.m_f == floatNumber.floatValue());
982         Object objNumber = getFloatAsObject();
983         h0.invoke(valueHolder, objNumber);
984         assertTrue(valueHolder.m_f == ((Float) objNumber).floatValue());
985         try {
986             h0.invoke(valueHolder, (Float)null);
987             fail();
988         } catch (NullPointerException e) {}
989 
990         h0.invoke(valueHolder, (byte)1);
991         h0.invoke(valueHolder, (short)2);
992         h0.invoke(valueHolder, 3);
993         h0.invoke(valueHolder, 4l);
994 
995         assertTrue(null == (Object) h0.invoke(valueHolder, 33));
996         assertTrue(0.0f == (float) h0.invoke(valueHolder, 33));
997         assertTrue(0l == (long) h0.invoke(valueHolder, 33));
998 
999         try {
1000             h0.invoke(valueHolder, 0.33);
1001             fail();
1002         } catch (WrongMethodTypeException e) {}
1003         try {
1004             Number doubleNumber = getDoubleAsNumber();
1005             h0.invoke(valueHolder, doubleNumber);
1006             fail();
1007         } catch (ClassCastException e) {}
1008         try {
1009             Number doubleNumber = null;
1010             h0.invoke(valueHolder, doubleNumber);
1011             fail();
1012         } catch (NullPointerException e) {}
1013         try {
1014             // Mismatched return type - float != void
1015             float tmp = (float)h0.invoke(valueHolder, 0.45f);
1016             assertTrue(tmp == 0.0);
1017         } catch (Exception e) { fail(); }
1018         try {
1019             h0.invoke(valueHolder, "bam");
1020             fail();
1021         } catch (WrongMethodTypeException e) {}
1022         try {
1023             String s = null;
1024             h0.invoke(valueHolder, s);
1025             fail();
1026         } catch (WrongMethodTypeException e) {}
1027     }
1028 
1029     @Test
testStaticSetter()1030     public void testStaticSetter() throws Throwable {
1031         MethodHandles.Lookup lookup = MethodHandles.lookup();
1032         MethodHandle h0 = lookup.findStaticSetter(ValueHolder.class, "s_f", float.class);
1033         h0.invoke(0.22f);
1034         h0.invoke(Float.valueOf(1.11f));
1035         Number floatNumber = Float.valueOf(0.88f);
1036         h0.invoke(floatNumber);
1037         assertTrue(ValueHolder.s_f == floatNumber.floatValue());
1038 
1039         try {
1040             h0.invoke((Float)null);
1041             fail();
1042         } catch (NullPointerException e) {}
1043 
1044         h0.invoke((byte)1);
1045         h0.invoke((short)2);
1046         h0.invoke(3);
1047         h0.invoke(4l);
1048 
1049         assertTrue(null == (Object) h0.invoke(33));
1050         assertTrue(0.0f == (float) h0.invoke(33));
1051         assertTrue(0l == (long) h0.invoke(33));
1052 
1053         try {
1054             h0.invoke(0.33);
1055             fail();
1056         } catch (WrongMethodTypeException e) {}
1057         try {
1058             Number doubleNumber = getDoubleAsNumber();
1059             h0.invoke(doubleNumber);
1060             fail();
1061         } catch (ClassCastException e) {}
1062         try {
1063             Number doubleNumber = Double.valueOf(1.01);
1064             doubleNumber = (doubleNumber.doubleValue() != 0.1) ? null : doubleNumber;
1065             h0.invoke(doubleNumber);
1066             fail();
1067         } catch (NullPointerException e) {}
1068         try {
1069             // Mismatched return type - float != void
1070             float tmp = (float)h0.invoke(0.45f);
1071             assertTrue(tmp == 0.0);
1072         } catch (Exception e) { fail(); }
1073         try {
1074             h0.invoke("bam");
1075             fail();
1076         } catch (WrongMethodTypeException e) {}
1077         try {
1078             String s = null;
1079             h0.invoke(s);
1080             fail();
1081         } catch (WrongMethodTypeException e) {}
1082     }
1083 
1084     @Test
throws_wmte_when_too_many_arguments_are_supplied()1085     public void throws_wmte_when_too_many_arguments_are_supplied() throws Throwable {
1086         MethodHandles.Lookup lookup = MethodHandles.lookup();
1087         MethodHandle setter = lookup.findStaticSetter(ValueHolder.class, "s_f", float.class);
1088 
1089         try {
1090             setter.invokeExact(0f, 1);
1091             fail("Should throw WMTE");
1092         } catch (WrongMethodTypeException ignored) {}
1093 
1094         try {
1095             setter.invokeExact(0f, 1, 2);
1096             fail("Should throw WMTE");
1097         } catch (WrongMethodTypeException ignored) {}
1098 
1099         try {
1100             setter.invokeExact(0f, 1, 2, 3);
1101             fail("Should throw WMTE");
1102         } catch (WrongMethodTypeException ignored) {}
1103 
1104         try {
1105             setter.invokeExact(0f, 1, 2, 3, 4);
1106             fail("Should throw WMTE");
1107         } catch (WrongMethodTypeException ignored) {}
1108 
1109         try {
1110             setter.invokeExact(0f, 1, 2, 3, 4, 5);
1111             fail("Should throw WMTE");
1112         } catch (WrongMethodTypeException ignored) {}
1113 
1114         try {
1115             setter.invokeExact(0f, 1, 2, 3, 4, 5, "str");
1116             fail("Should throw WMTE");
1117         } catch (WrongMethodTypeException ignored) {}
1118     }
1119 }
1120