• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 import java.lang.invoke.MethodHandle;
17 import java.lang.invoke.MethodHandles;
18 import java.lang.invoke.WrongMethodTypeException;
19 
20 public class Main {
21 
22     public static class ValueHolder {
23         public boolean m_z = false;
24         public byte m_b = 0;
25         public char m_c = 'a';
26         public short m_s = 0;
27         public int m_i = 0;
28         public float m_f = 0.0f;
29         public double m_d = 0.0;
30         public long m_j = 0;
31         public String m_l = "a";
32 
33         public static boolean s_z;
34         public static byte s_b;
35         public static char s_c;
36         public static short s_s;
37         public static int s_i;
38         public static float s_f;
39         public static double s_d;
40         public static long s_j;
41         public static String s_l;
42 
43         public final int m_fi = 0xa5a5a5a5;
44         public static final int s_fi = 0x5a5a5a5a;
45     }
46 
47     public static class Tester {
assertActualAndExpectedMatch(boolean actual, boolean expected)48         public static void assertActualAndExpectedMatch(boolean actual, boolean expected)
49                 throws AssertionError {
50             if (actual != expected) {
51                 throw new AssertionError("Actual != Expected (" + actual + " != " + expected + ")");
52             }
53         }
54 
assertTrue(boolean value)55         public static void assertTrue(boolean value) throws AssertionError {
56             if (!value) {
57                 throw new AssertionError("Value is not true");
58             }
59         }
60 
unreachable()61         public static void unreachable() throws Throwable{
62             throw new Error("unreachable");
63         }
64     }
65 
66     public static class InvokeExactTester extends Tester {
67         private enum PrimitiveType {
68             Boolean,
69             Byte,
70             Char,
71             Short,
72             Int,
73             Long,
74             Float,
75             Double,
76             String,
77         }
78 
79         private enum AccessorType {
80             IPUT,
81             SPUT,
82             IGET,
83             SGET,
84         }
85 
setByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)86         static void setByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)
87                 throws Throwable {
88             boolean exceptionThrown = false;
89             try {
90                 if (v == null) {
91                     m.invokeExact(value);
92                 }
93                 else {
94                     m.invokeExact(v, value);
95                 }
96             }
97             catch (WrongMethodTypeException e) {
98                 exceptionThrown = true;
99             }
100             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
101         }
102 
setByte(MethodHandle m, byte value, boolean expectFailure)103         static void setByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable {
104             setByte(m, null, value, expectFailure);
105         }
106 
getByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)107         static void getByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)
108                 throws Throwable {
109             boolean exceptionThrown = false;
110             try {
111                 final byte got;
112                 if (v == null) {
113                     got = (byte)m.invokeExact();
114                 } else {
115                     got = (byte)m.invokeExact(v);
116                 }
117                 assertTrue(got == value);
118             }
119             catch (WrongMethodTypeException e) {
120                 exceptionThrown = true;
121             }
122             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
123         }
124 
getByte(MethodHandle m, byte value, boolean expectFailure)125         static void getByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable {
126             getByte(m, null, value, expectFailure);
127         }
128 
setChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)129         static void setChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)
130                 throws Throwable {
131             boolean exceptionThrown = false;
132             try {
133                 if (v == null) {
134                     m.invokeExact(value);
135                 }
136                 else {
137                     m.invokeExact(v, value);
138                 }
139             }
140             catch (WrongMethodTypeException e) {
141                 exceptionThrown = true;
142             }
143             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
144         }
145 
setChar(MethodHandle m, char value, boolean expectFailure)146         static void setChar(MethodHandle m, char value, boolean expectFailure) throws Throwable {
147             setChar(m, null, value, expectFailure);
148         }
149 
getChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)150         static void getChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)
151                 throws Throwable {
152             boolean exceptionThrown = false;
153             try {
154                 final char got;
155                 if (v == null) {
156                     got = (char)m.invokeExact();
157                 } else {
158                     got = (char)m.invokeExact(v);
159                 }
160                 assertTrue(got == value);
161             }
162             catch (WrongMethodTypeException e) {
163                 exceptionThrown = true;
164             }
165             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
166         }
167 
getChar(MethodHandle m, char value, boolean expectFailure)168         static void getChar(MethodHandle m, char value, boolean expectFailure) throws Throwable {
169             getChar(m, null, value, expectFailure);
170         }
171 
setShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)172         static void setShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)
173                 throws Throwable {
174             boolean exceptionThrown = false;
175             try {
176                 if (v == null) {
177                     m.invokeExact(value);
178                 }
179                 else {
180                     m.invokeExact(v, value);
181                 }
182             }
183             catch (WrongMethodTypeException e) {
184                 exceptionThrown = true;
185             }
186             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
187         }
188 
setShort(MethodHandle m, short value, boolean expectFailure)189         static void setShort(MethodHandle m, short value, boolean expectFailure) throws Throwable {
190             setShort(m, null, value, expectFailure);
191         }
192 
getShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)193         static void getShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)
194                 throws Throwable {
195             boolean exceptionThrown = false;
196             try {
197                 final short got = (v == null) ? (short)m.invokeExact() : (short)m.invokeExact(v);
198                 assertTrue(got == value);
199             }
200             catch (WrongMethodTypeException e) {
201                 exceptionThrown = true;
202             }
203             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
204         }
205 
getShort(MethodHandle m, short value, boolean expectFailure)206         static void getShort(MethodHandle m, short value, boolean expectFailure) throws Throwable {
207             getShort(m, null, value, expectFailure);
208         }
209 
setInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)210         static void setInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)
211                 throws Throwable {
212             boolean exceptionThrown = false;
213             try {
214                 if (v == null) {
215                     m.invokeExact(value);
216                 }
217                 else {
218                     m.invokeExact(v, value);
219                 }
220             }
221             catch (WrongMethodTypeException e) {
222                 exceptionThrown = true;
223             }
224             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
225         }
226 
setInt(MethodHandle m, int value, boolean expectFailure)227         static void setInt(MethodHandle m, int value, boolean expectFailure) throws Throwable {
228             setInt(m, null, value, expectFailure);
229         }
230 
getInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)231         static void getInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)
232                 throws Throwable {
233             boolean exceptionThrown = false;
234             try {
235                 final int got = (v == null) ? (int)m.invokeExact() : (int)m.invokeExact(v);
236                 assertTrue(got == value);
237             }
238             catch (WrongMethodTypeException e) {
239                 exceptionThrown = true;
240             }
241             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
242         }
243 
getInt(MethodHandle m, int value, boolean expectFailure)244         static void getInt(MethodHandle m, int value, boolean expectFailure) throws Throwable {
245             getInt(m, null, value, expectFailure);
246         }
247 
setLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)248         static void setLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)
249                 throws Throwable {
250             boolean exceptionThrown = false;
251             try {
252                 if (v == null) {
253                     m.invokeExact(value);
254                 }
255                 else {
256                     m.invokeExact(v, value);
257                 }
258             }
259             catch (WrongMethodTypeException e) {
260                 exceptionThrown = true;
261             }
262             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
263         }
264 
setLong(MethodHandle m, long value, boolean expectFailure)265         static void setLong(MethodHandle m, long value, boolean expectFailure) throws Throwable {
266             setLong(m, null, value, expectFailure);
267         }
268 
getLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)269         static void getLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)
270                 throws Throwable {
271             boolean exceptionThrown = false;
272             try {
273                 final long got = (v == null) ? (long)m.invokeExact() : (long)m.invokeExact(v);
274                 assertTrue(got == value);
275             }
276             catch (WrongMethodTypeException e) {
277                 exceptionThrown = true;
278             }
279             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
280         }
281 
getLong(MethodHandle m, long value, boolean expectFailure)282         static void getLong(MethodHandle m, long value, boolean expectFailure) throws Throwable {
283             getLong(m, null, value, expectFailure);
284         }
285 
setFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)286         static void setFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)
287                 throws Throwable {
288             boolean exceptionThrown = false;
289             try {
290                 if (v == null) {
291                     m.invokeExact(value);
292                 }
293                 else {
294                     m.invokeExact(v, value);
295                 }
296             }
297             catch (WrongMethodTypeException e) {
298                 exceptionThrown = true;
299             }
300             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
301         }
302 
setFloat(MethodHandle m, float value, boolean expectFailure)303         static void setFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable {
304             setFloat(m, null, value, expectFailure);
305         }
306 
getFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)307         static void getFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)
308                 throws Throwable {
309             boolean exceptionThrown = false;
310             try {
311                 final float got = (v == null) ? (float)m.invokeExact() : (float)m.invokeExact(v);
312                 assertTrue(got == value);
313             }
314             catch (WrongMethodTypeException e) {
315                 exceptionThrown = true;
316             }
317             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
318         }
319 
getFloat(MethodHandle m, float value, boolean expectFailure)320         static void getFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable {
321             getFloat(m, null, value, expectFailure);
322         }
323 
setDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)324         static void setDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)
325                 throws Throwable {
326             boolean exceptionThrown = false;
327             try {
328                 if (v == null) {
329                     m.invokeExact(value);
330                 }
331                 else {
332                     m.invokeExact(v, value);
333                 }
334             }
335             catch (WrongMethodTypeException e) {
336                 exceptionThrown = true;
337             }
338             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
339         }
340 
setDouble(MethodHandle m, double value, boolean expectFailure)341         static void setDouble(MethodHandle m, double value, boolean expectFailure)
342                 throws Throwable {
343             setDouble(m, null, value, expectFailure);
344         }
345 
getDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)346         static void getDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)
347                 throws Throwable {
348             boolean exceptionThrown = false;
349             try {
350                 final double got = (v == null) ? (double)m.invokeExact() : (double)m.invokeExact(v);
351                 assertTrue(got == value);
352             }
353             catch (WrongMethodTypeException e) {
354                 exceptionThrown = true;
355             }
356             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
357         }
358 
getDouble(MethodHandle m, double value, boolean expectFailure)359         static void getDouble(MethodHandle m, double value, boolean expectFailure)
360                 throws Throwable {
361             getDouble(m, null, value, expectFailure);
362         }
363 
setString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)364         static void setString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)
365                 throws Throwable {
366             boolean exceptionThrown = false;
367             try {
368                 if (v == null) {
369                     m.invokeExact(value);
370                 }
371                 else {
372                     m.invokeExact(v, value);
373                 }
374             }
375             catch (WrongMethodTypeException e) {
376                 exceptionThrown = true;
377             }
378             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
379         }
380 
setString(MethodHandle m, String value, boolean expectFailure)381         static void setString(MethodHandle m, String value, boolean expectFailure)
382                 throws Throwable {
383             setString(m, null, value, expectFailure);
384         }
385 
getString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)386         static void getString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)
387                 throws Throwable {
388             boolean exceptionThrown = false;
389             try {
390                 final String got = (v == null) ? (String)m.invokeExact() : (String)m.invokeExact(v);
391                 assertTrue(got.equals(value));
392             }
393             catch (WrongMethodTypeException e) {
394                 exceptionThrown = true;
395             }
396             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
397         }
398 
getString(MethodHandle m, String value, boolean expectFailure)399         static void getString(MethodHandle m, String value, boolean expectFailure)
400                 throws Throwable {
401             getString(m, null, value, expectFailure);
402         }
403 
setBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)404         static void setBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)
405                 throws Throwable {
406             boolean exceptionThrown = false;
407             try {
408                 if (v == null) {
409                     m.invokeExact(value);
410                 }
411                 else {
412                     m.invokeExact(v, value);
413                 }
414             }
415             catch (WrongMethodTypeException e) {
416                 exceptionThrown = true;
417             }
418             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
419         }
420 
setBoolean(MethodHandle m, boolean value, boolean expectFailure)421         static void setBoolean(MethodHandle m, boolean value, boolean expectFailure)
422                 throws Throwable {
423             setBoolean(m, null, value, expectFailure);
424         }
425 
getBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)426         static void getBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)
427                 throws Throwable {
428             boolean exceptionThrown = false;
429             try {
430                 final boolean got =
431                         (v == null) ? (boolean)m.invokeExact() : (boolean)m.invokeExact(v);
432                 assertTrue(got == value);
433             }
434             catch (WrongMethodTypeException e) {
435                 exceptionThrown = true;
436             }
437             assertActualAndExpectedMatch(exceptionThrown, expectFailure);
438         }
439 
getBoolean(MethodHandle m, boolean value, boolean expectFailure)440         static void getBoolean(MethodHandle m, boolean value, boolean expectFailure)
441                 throws Throwable {
442             getBoolean(m, null, value, expectFailure);
443         }
444 
resultFor(PrimitiveType actualType, PrimitiveType expectedType, AccessorType actualAccessor, AccessorType expectedAccessor)445         static boolean resultFor(PrimitiveType actualType, PrimitiveType expectedType,
446                                  AccessorType actualAccessor,
447                                  AccessorType expectedAccessor) {
448             return (actualType != expectedType) || (actualAccessor != expectedAccessor);
449         }
450 
tryAccessor(MethodHandle methodHandle, ValueHolder valueHolder, PrimitiveType primitive, Object value, AccessorType accessor)451         static void tryAccessor(MethodHandle methodHandle,
452                                 ValueHolder valueHolder,
453                                 PrimitiveType primitive,
454                                 Object value,
455                                 AccessorType accessor) throws Throwable {
456             boolean booleanValue =
457                     value instanceof Boolean ? ((Boolean)value).booleanValue() : false;
458             setBoolean(methodHandle, valueHolder, booleanValue,
459                        resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.IPUT));
460             setBoolean(methodHandle, booleanValue,
461                        resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.SPUT));
462             getBoolean(methodHandle, valueHolder, booleanValue,
463                        resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.IGET));
464             getBoolean(methodHandle, booleanValue,
465                        resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.SGET));
466 
467             byte byteValue = value instanceof Byte ? ((Byte)value).byteValue() : (byte)0;
468             setByte(methodHandle, valueHolder, byteValue,
469                     resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.IPUT));
470             setByte(methodHandle, byteValue,
471                     resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.SPUT));
472             getByte(methodHandle, valueHolder, byteValue,
473                     resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.IGET));
474             getByte(methodHandle, byteValue,
475                     resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.SGET));
476 
477             char charValue = value instanceof Character ? ((Character)value).charValue() : 'z';
478             setChar(methodHandle, valueHolder, charValue,
479                     resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.IPUT));
480             setChar(methodHandle, charValue,
481                     resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.SPUT));
482             getChar(methodHandle, valueHolder, charValue,
483                     resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.IGET));
484             getChar(methodHandle, charValue,
485                     resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.SGET));
486 
487             short shortValue = value instanceof Short ? ((Short)value).shortValue() : (short)0;
488             setShort(methodHandle, valueHolder, shortValue,
489                      resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.IPUT));
490             setShort(methodHandle, shortValue,
491                     resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.SPUT));
492             getShort(methodHandle, valueHolder, shortValue,
493                      resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.IGET));
494             getShort(methodHandle, shortValue,
495                     resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.SGET));
496 
497             int intValue = value instanceof Integer ? ((Integer)value).intValue() : -1;
498             setInt(methodHandle, valueHolder, intValue,
499                    resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.IPUT));
500             setInt(methodHandle, intValue,
501                    resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.SPUT));
502             getInt(methodHandle, valueHolder, intValue,
503                    resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.IGET));
504             getInt(methodHandle, intValue,
505                    resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.SGET));
506 
507             long longValue = value instanceof Long ? ((Long)value).longValue() : (long)-1;
508             setLong(methodHandle, valueHolder, longValue,
509                     resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.IPUT));
510             setLong(methodHandle, longValue,
511                     resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.SPUT));
512             getLong(methodHandle, valueHolder, longValue,
513                     resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.IGET));
514             getLong(methodHandle, longValue,
515                     resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.SGET));
516 
517             float floatValue = value instanceof Float ? ((Float)value).floatValue() : -1.0f;
518             setFloat(methodHandle, valueHolder, floatValue,
519                     resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.IPUT));
520             setFloat(methodHandle, floatValue,
521                     resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.SPUT));
522             getFloat(methodHandle, valueHolder, floatValue,
523                     resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.IGET));
524             getFloat(methodHandle, floatValue,
525                      resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.SGET));
526 
527             double doubleValue = value instanceof Double ? ((Double)value).doubleValue() : -1.0;
528             setDouble(methodHandle, valueHolder, doubleValue,
529                       resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.IPUT));
530             setDouble(methodHandle, doubleValue,
531                       resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.SPUT));
532             getDouble(methodHandle, valueHolder, doubleValue,
533                       resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.IGET));
534             getDouble(methodHandle, doubleValue,
535                       resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.SGET));
536 
537             String stringValue = value instanceof String ? ((String) value) : "No Spock, no";
538             setString(methodHandle, valueHolder, stringValue,
539                       resultFor(primitive, PrimitiveType.String, accessor, AccessorType.IPUT));
540             setString(methodHandle, stringValue,
541                       resultFor(primitive, PrimitiveType.String, accessor, AccessorType.SPUT));
542             getString(methodHandle, valueHolder, stringValue,
543                       resultFor(primitive, PrimitiveType.String, accessor, AccessorType.IGET));
544             getString(methodHandle, stringValue,
545                       resultFor(primitive, PrimitiveType.String, accessor, AccessorType.SGET));
546         }
547 
main()548         public static void main() throws Throwable {
549             ValueHolder valueHolder = new ValueHolder();
550             MethodHandles.Lookup lookup = MethodHandles.lookup();
551 
552             boolean [] booleans = { false, true, false };
553             for (boolean b : booleans) {
554                 Boolean boxed = new Boolean(b);
555                 tryAccessor(lookup.findSetter(ValueHolder.class, "m_z", boolean.class),
556                             valueHolder, PrimitiveType.Boolean, boxed, AccessorType.IPUT);
557                 tryAccessor(lookup.findGetter(ValueHolder.class, "m_z", boolean.class),
558                             valueHolder, PrimitiveType.Boolean, boxed, AccessorType.IGET);
559                 assertTrue(valueHolder.m_z == b);
560                 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_z", boolean.class),
561                             valueHolder, PrimitiveType.Boolean, boxed, AccessorType.SPUT);
562                 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_z", boolean.class),
563                             valueHolder, PrimitiveType.Boolean, boxed, AccessorType.SGET);
564                 assertTrue(ValueHolder.s_z == b);
565             }
566 
567             byte [] bytes = { (byte)0x73, (byte)0xfe };
568             for (byte b : bytes) {
569                 Byte boxed = new Byte(b);
570                 tryAccessor(lookup.findSetter(ValueHolder.class, "m_b", byte.class),
571                             valueHolder, PrimitiveType.Byte, boxed, AccessorType.IPUT);
572                 tryAccessor(lookup.findGetter(ValueHolder.class, "m_b", byte.class),
573                             valueHolder, PrimitiveType.Byte, boxed, AccessorType.IGET);
574                 assertTrue(valueHolder.m_b == b);
575                 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_b", byte.class),
576                             valueHolder, PrimitiveType.Byte, boxed, AccessorType.SPUT);
577                 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_b", byte.class),
578                             valueHolder, PrimitiveType.Byte, boxed, AccessorType.SGET);
579                 assertTrue(ValueHolder.s_b == b);
580             }
581 
582             char [] chars = { 'a', 'b', 'c' };
583             for (char c : chars) {
584                 Character boxed = new Character(c);
585                 tryAccessor(lookup.findSetter(ValueHolder.class, "m_c", char.class),
586                             valueHolder, PrimitiveType.Char, boxed, AccessorType.IPUT);
587                 tryAccessor(lookup.findGetter(ValueHolder.class, "m_c", char.class),
588                             valueHolder, PrimitiveType.Char, boxed, AccessorType.IGET);
589                 assertTrue(valueHolder.m_c == c);
590                 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_c", char.class),
591                             valueHolder, PrimitiveType.Char, boxed, AccessorType.SPUT);
592                 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_c", char.class),
593                             valueHolder, PrimitiveType.Char, boxed, AccessorType.SGET);
594                 assertTrue(ValueHolder.s_c == c);
595             }
596 
597             short [] shorts = { (short)0x1234, (short)0x4321 };
598             for (short s : shorts) {
599                 Short boxed = new Short(s);
600                 tryAccessor(lookup.findSetter(ValueHolder.class, "m_s", short.class),
601                             valueHolder, PrimitiveType.Short, boxed, AccessorType.IPUT);
602                 tryAccessor(lookup.findGetter(ValueHolder.class, "m_s", short.class),
603                             valueHolder, PrimitiveType.Short, boxed, AccessorType.IGET);
604                 assertTrue(valueHolder.m_s == s);
605                 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_s", short.class),
606                             valueHolder, PrimitiveType.Short, boxed, AccessorType.SPUT);
607                 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_s", short.class),
608                             valueHolder, PrimitiveType.Short, boxed, AccessorType.SGET);
609                 assertTrue(ValueHolder.s_s == s);
610             }
611 
612             int [] ints = { -100000000, 10000000 };
613             for (int i : ints) {
614                 Integer boxed = new Integer(i);
615                 tryAccessor(lookup.findSetter(ValueHolder.class, "m_i", int.class),
616                             valueHolder, PrimitiveType.Int, boxed, AccessorType.IPUT);
617                 tryAccessor(lookup.findGetter(ValueHolder.class, "m_i", int.class),
618                             valueHolder, PrimitiveType.Int, boxed, AccessorType.IGET);
619                 assertTrue(valueHolder.m_i == i);
620                 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_i", int.class),
621                             valueHolder, PrimitiveType.Int, boxed, AccessorType.SPUT);
622                 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_i", int.class),
623                             valueHolder, PrimitiveType.Int, boxed, AccessorType.SGET);
624                 assertTrue(ValueHolder.s_i == i);
625             }
626 
627             float [] floats = { 0.99f, -1.23e-17f };
628             for (float f : floats) {
629                 Float boxed = new Float(f);
630                 tryAccessor(lookup.findSetter(ValueHolder.class, "m_f", float.class),
631                             valueHolder, PrimitiveType.Float, boxed, AccessorType.IPUT);
632                 tryAccessor(lookup.findGetter(ValueHolder.class, "m_f", float.class),
633                             valueHolder, PrimitiveType.Float, boxed, AccessorType.IGET);
634                 assertTrue(valueHolder.m_f == f);
635                 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_f", float.class),
636                             valueHolder, PrimitiveType.Float, boxed, AccessorType.SPUT);
637                 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_f", float.class),
638                             valueHolder, PrimitiveType.Float, boxed, AccessorType.SGET);
639                 assertTrue(ValueHolder.s_f == f);
640             }
641 
642             double [] doubles = { 0.44444444444e37, -0.555555555e-37 };
643             for (double d : doubles) {
644                 Double boxed = new Double(d);
645                 tryAccessor(lookup.findSetter(ValueHolder.class, "m_d", double.class),
646                             valueHolder, PrimitiveType.Double, boxed, AccessorType.IPUT);
647                 tryAccessor(lookup.findGetter(ValueHolder.class, "m_d", double.class),
648                             valueHolder, PrimitiveType.Double, boxed, AccessorType.IGET);
649                 assertTrue(valueHolder.m_d == d);
650                 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_d", double.class),
651                             valueHolder, PrimitiveType.Double, boxed, AccessorType.SPUT);
652                 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_d", double.class),
653                             valueHolder, PrimitiveType.Double, boxed, AccessorType.SGET);
654                 assertTrue(ValueHolder.s_d == d);
655             }
656 
657             long [] longs = { 0x0123456789abcdefl, 0xfedcba9876543210l };
658             for (long j : longs) {
659                 Long boxed = new Long(j);
660                 tryAccessor(lookup.findSetter(ValueHolder.class, "m_j", long.class),
661                             valueHolder, PrimitiveType.Long, boxed, AccessorType.IPUT);
662                 tryAccessor(lookup.findGetter(ValueHolder.class, "m_j", long.class),
663                             valueHolder, PrimitiveType.Long, boxed, AccessorType.IGET);
664                 assertTrue(valueHolder.m_j == j);
665                 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_j", long.class),
666                             valueHolder, PrimitiveType.Long, boxed, AccessorType.SPUT);
667                 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_j", long.class),
668                             valueHolder, PrimitiveType.Long, boxed, AccessorType.SGET);
669                 assertTrue(ValueHolder.s_j == j);
670             }
671 
672             String [] strings = { "octopus", "crab" };
673             for (String s : strings) {
674                 tryAccessor(lookup.findSetter(ValueHolder.class, "m_l", String.class),
675                             valueHolder, PrimitiveType.String, s, AccessorType.IPUT);
676                 tryAccessor(lookup.findGetter(ValueHolder.class, "m_l", String.class),
677                             valueHolder, PrimitiveType.String, s, AccessorType.IGET);
678                 assertTrue(s.equals(valueHolder.m_l));
679                 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_l", String.class),
680                             valueHolder, PrimitiveType.String, s, AccessorType.SPUT);
681                 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_l", String.class),
682                             valueHolder, PrimitiveType.String, s, AccessorType.SGET);
683                 assertTrue(s.equals(ValueHolder.s_l));
684             }
685 
686             System.out.println("Passed MethodHandle.invokeExact() tests for accessors.");
687         }
688     }
689 
690     public static class FindAccessorTester extends Tester {
main()691         public static void main() throws Throwable {
692             // NB having a static field test here is essential for
693             // this test. MethodHandles need to ensure the class
694             // (ValueHolder) is initialized. This happens in the
695             // invoke-polymorphic dispatch.
696             MethodHandles.Lookup lookup = MethodHandles.lookup();
697             try {
698                 MethodHandle mh = lookup.findStaticGetter(ValueHolder.class, "s_fi", int.class);
699                 int initialValue = (int)mh.invokeExact();
700                 System.out.println(initialValue);
701             } catch (NoSuchFieldException e) { unreachable(); }
702             try {
703                 MethodHandle mh = lookup.findStaticSetter(ValueHolder.class, "s_i", int.class);
704                 mh.invokeExact(0);
705             } catch (NoSuchFieldException e) { unreachable(); }
706             try {
707                 lookup.findStaticGetter(ValueHolder.class, "s_fi", byte.class);
708                 unreachable();
709             } catch (NoSuchFieldException e) {}
710             try {
711                 lookup.findGetter(ValueHolder.class, "s_fi", byte.class);
712                 unreachable();
713             } catch (NoSuchFieldException e) {}
714             try {
715                 lookup.findStaticSetter(ValueHolder.class, "s_fi", int.class);
716                 unreachable();
717             } catch (IllegalAccessException e) {}
718 
719             lookup.findGetter(ValueHolder.class, "m_fi", int.class);
720             try {
721                 lookup.findGetter(ValueHolder.class, "m_fi", byte.class);
722                 unreachable();
723             } catch (NoSuchFieldException e) {}
724             try {
725                 lookup.findStaticGetter(ValueHolder.class, "m_fi", byte.class);
726                 unreachable();
727             } catch (NoSuchFieldException e) {}
728             try {
729                 lookup.findSetter(ValueHolder.class, "m_fi", int.class);
730                 unreachable();
731             } catch (IllegalAccessException e) {}
732 
733             System.out.println("Passed MethodHandles.Lookup tests for accessors.");
734         }
735     }
736 
737     public static class InvokeTester extends Tester {
testStaticGetter()738         private static void testStaticGetter() throws Throwable {
739             MethodHandles.Lookup lookup = MethodHandles.lookup();
740             MethodHandle h0 = lookup.findStaticGetter(ValueHolder.class, "s_fi", int.class);
741             h0.invoke();
742             Number t = (Number)h0.invoke();
743             int u = (int)h0.invoke();
744             Integer v = (Integer)h0.invoke();
745             long w = (long)h0.invoke();
746             try {
747                 byte x = (byte)h0.invoke();
748                 unreachable();
749             } catch (WrongMethodTypeException e) {}
750             try {
751                 String y = (String)h0.invoke();
752                 unreachable();
753             } catch (WrongMethodTypeException e) {}
754             try {
755                 Long z = (Long)h0.invoke();
756                 unreachable();
757             } catch (WrongMethodTypeException e) {}
758         }
759 
testMemberGetter()760         private static void testMemberGetter() throws Throwable {
761             ValueHolder valueHolder = new ValueHolder();
762             MethodHandles.Lookup lookup = MethodHandles.lookup();
763             MethodHandle h0 = lookup.findGetter(ValueHolder.class, "m_fi", int.class);
764             h0.invoke(valueHolder);
765             Number t = (Number)h0.invoke(valueHolder);
766             int u = (int)h0.invoke(valueHolder);
767             Integer v = (Integer)h0.invoke(valueHolder);
768             long w = (long)h0.invoke(valueHolder);
769             try {
770                 byte x = (byte)h0.invoke(valueHolder);
771                 unreachable();
772             } catch (WrongMethodTypeException e) {}
773             try {
774                 String y = (String)h0.invoke(valueHolder);
775                 unreachable();
776             } catch (WrongMethodTypeException e) {}
777             try {
778                 Long z = (Long)h0.invoke(valueHolder);
779                 unreachable();
780             } catch (WrongMethodTypeException e) {}
781         }
782 
getDoubleAsNumber()783         /*package*/ static Number getDoubleAsNumber() {
784             return new Double(1.4e77);
785         }
getFloatAsNumber()786         /*package*/ static Number getFloatAsNumber() {
787             return new Float(7.77);
788         }
getFloatAsObject()789         /*package*/ static Object getFloatAsObject() {
790             return new Float(-7.77);
791         }
792 
testMemberSetter()793         private static void testMemberSetter() throws Throwable {
794             ValueHolder valueHolder = new ValueHolder();
795             MethodHandles.Lookup lookup = MethodHandles.lookup();
796             MethodHandle h0 = lookup.findSetter(ValueHolder.class, "m_f", float.class);
797             MethodHandle s0 = lookup.findSetter(ValueHolder.class, "m_s", short.class);
798             h0.invoke(valueHolder, 0.22f);
799             h0.invoke(valueHolder, new Float(1.11f));
800             Number floatNumber = getFloatAsNumber();
801             h0.invoke(valueHolder, floatNumber);
802             assertTrue(valueHolder.m_f == floatNumber.floatValue());
803             Object objNumber = getFloatAsObject();
804             h0.invoke(valueHolder, objNumber);
805             assertTrue(valueHolder.m_f == ((Float) objNumber).floatValue());
806             try {
807               h0.invoke(valueHolder, (Float)null);
808               unreachable();
809             } catch (NullPointerException e) {}
810 
811             // Test that type conversion checks work on small field types.
812             short temp = (short)s0.invoke(valueHolder, new Byte((byte)45));
813             assertTrue(temp == 0);
814             assertTrue(valueHolder.m_s == 45);
815 
816             h0.invoke(valueHolder, (byte)1);
817             h0.invoke(valueHolder, (short)2);
818             h0.invoke(valueHolder, 3);
819             h0.invoke(valueHolder, 4l);
820 
821             assertTrue(null == (Object) h0.invoke(valueHolder, 33));
822             assertTrue(0.0f == (float) h0.invoke(valueHolder, 33));
823             assertTrue(0l == (long) h0.invoke(valueHolder, 33));
824 
825             try {
826                 h0.invoke(valueHolder, 0.33);
827                 unreachable();
828             } catch (WrongMethodTypeException e) {}
829             try {
830                 Number doubleNumber = getDoubleAsNumber();
831                 h0.invoke(valueHolder, doubleNumber);
832                 unreachable();
833             } catch (ClassCastException e) {}
834             try {
835                 Number doubleNumber = null;
836                 h0.invoke(valueHolder, doubleNumber);
837                 unreachable();
838             } catch (NullPointerException e) {}
839             try {
840                 // Mismatched return type - float != void
841                 float tmp = (float)h0.invoke(valueHolder, 0.45f);
842                 assertTrue(tmp == 0.0);
843             } catch (Exception e) { unreachable(); }
844             try {
845                 h0.invoke(valueHolder, "bam");
846                 unreachable();
847             } catch (WrongMethodTypeException e) {}
848             try {
849                 String s = null;
850                 h0.invoke(valueHolder, s);
851                 unreachable();
852             } catch (WrongMethodTypeException e) {}
853         }
854 
testStaticSetter()855         private static void testStaticSetter() throws Throwable {
856             MethodHandles.Lookup lookup = MethodHandles.lookup();
857             MethodHandle s0 = lookup.findStaticSetter(ValueHolder.class, "s_s", short.class);
858             MethodHandle h0 = lookup.findStaticSetter(ValueHolder.class, "s_f", float.class);
859             h0.invoke(0.22f);
860             h0.invoke(new Float(1.11f));
861             Number floatNumber = new Float(0.88f);
862             h0.invoke(floatNumber);
863             assertTrue(ValueHolder.s_f == floatNumber.floatValue());
864 
865             try {
866               h0.invoke((Float)null);
867               unreachable();
868             } catch (NullPointerException e) {}
869 
870             // Test that type conversion checks work on small field types.
871             short temp = (short)s0.invoke(new Byte((byte)45));
872             assertTrue(temp == 0);
873             assertTrue(ValueHolder.s_s == 45);
874 
875             h0.invoke((byte)1);
876             h0.invoke((short)2);
877             h0.invoke(3);
878             h0.invoke(4l);
879 
880             assertTrue(null == (Object) h0.invoke(33));
881             assertTrue(0.0f == (float) h0.invoke(33));
882             assertTrue(0l == (long) h0.invoke(33));
883 
884             try {
885                 h0.invoke(0.33);
886                 unreachable();
887             } catch (WrongMethodTypeException e) {}
888             try {
889                 Number doubleNumber = getDoubleAsNumber();
890                 h0.invoke(doubleNumber);
891                 unreachable();
892             } catch (ClassCastException e) {}
893             try {
894                 Number doubleNumber = new Double(1.01);
895                 doubleNumber = (doubleNumber.doubleValue() != 0.1) ? null : doubleNumber;
896                 h0.invoke(doubleNumber);
897                 unreachable();
898             } catch (NullPointerException e) {}
899             try {
900                 // Mismatched return type - float != void
901                 float tmp = (float)h0.invoke(0.45f);
902                 assertTrue(tmp == 0.0);
903             } catch (Exception e) { unreachable(); }
904             try {
905                 h0.invoke("bam");
906                 unreachable();
907             } catch (WrongMethodTypeException e) {}
908             try {
909                 String s = null;
910                 h0.invoke(s);
911                 unreachable();
912             } catch (WrongMethodTypeException e) {}
913         }
914 
main()915         public static void main() throws Throwable{
916             testStaticGetter();
917             testMemberGetter();
918             testStaticSetter();
919             testMemberSetter();
920             System.out.println("Passed MethodHandle.invoke() tests for accessors.");
921         }
922     }
923 
main(String[] args)924     public static void main(String[] args) throws Throwable {
925         // FindAccessor test should be the first test class in this
926         // file to ensure class initialization test is run.
927         FindAccessorTester.main();
928         InvokeExactTester.main();
929         InvokeTester.main();
930     }
931 }
932