blob: 824a436f3b8c4e8d4fad47e1ffb04cf9da08effe [file] [log] [blame]
Orion Hodson3d617ac2016-10-19 14:00:46 +01001/*
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 */
16import java.lang.invoke.MethodHandle;
17import java.lang.invoke.MethodHandles;
18import java.lang.invoke.WrongMethodTypeException;
19
20public 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
Orion Hodsonba28f9f2016-10-26 10:56:25 +010047 public static class Tester {
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
55 public static void assertTrue(boolean value) throws AssertionError {
56 if (!value) {
57 throw new AssertionError("Value is not true");
58 }
59 }
60
61 public static void unreachable() throws Throwable{
62 throw new Error("unreachable");
63 }
64 }
65
66 public static class InvokeExactTester extends Tester {
Orion Hodson3d617ac2016-10-19 14:00:46 +010067 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
Orion Hodson3d617ac2016-10-19 14:00:46 +010086 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
103 static void setByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable {
104 setByte(m, null, value, expectFailure);
105 }
106
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
125 static void getByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable {
126 getByte(m, null, value, expectFailure);
127 }
128
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
146 static void setChar(MethodHandle m, char value, boolean expectFailure) throws Throwable {
147 setChar(m, null, value, expectFailure);
148 }
149
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
168 static void getChar(MethodHandle m, char value, boolean expectFailure) throws Throwable {
169 getChar(m, null, value, expectFailure);
170 }
171
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
189 static void setShort(MethodHandle m, short value, boolean expectFailure) throws Throwable {
190 setShort(m, null, value, expectFailure);
191 }
192
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
206 static void getShort(MethodHandle m, short value, boolean expectFailure) throws Throwable {
207 getShort(m, null, value, expectFailure);
208 }
209
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
227 static void setInt(MethodHandle m, int value, boolean expectFailure) throws Throwable {
228 setInt(m, null, value, expectFailure);
229 }
230
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
244 static void getInt(MethodHandle m, int value, boolean expectFailure) throws Throwable {
245 getInt(m, null, value, expectFailure);
246 }
247
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
265 static void setLong(MethodHandle m, long value, boolean expectFailure) throws Throwable {
266 setLong(m, null, value, expectFailure);
267 }
268
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
282 static void getLong(MethodHandle m, long value, boolean expectFailure) throws Throwable {
283 getLong(m, null, value, expectFailure);
284 }
285
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
303 static void setFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable {
304 setFloat(m, null, value, expectFailure);
305 }
306
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
320 static void getFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable {
321 getFloat(m, null, value, expectFailure);
322 }
323
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
341 static void setDouble(MethodHandle m, double value, boolean expectFailure)
342 throws Throwable {
343 setDouble(m, null, value, expectFailure);
344 }
345
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
359 static void getDouble(MethodHandle m, double value, boolean expectFailure)
360 throws Throwable {
361 getDouble(m, null, value, expectFailure);
362 }
363
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
381 static void setString(MethodHandle m, String value, boolean expectFailure)
382 throws Throwable {
383 setString(m, null, value, expectFailure);
384 }
385
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
399 static void getString(MethodHandle m, String value, boolean expectFailure)
400 throws Throwable {
401 getString(m, null, value, expectFailure);
402 }
403
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
421 static void setBoolean(MethodHandle m, boolean value, boolean expectFailure)
422 throws Throwable {
423 setBoolean(m, null, value, expectFailure);
424 }
425
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
440 static void getBoolean(MethodHandle m, boolean value, boolean expectFailure)
441 throws Throwable {
442 getBoolean(m, null, value, expectFailure);
443 }
444
445 static boolean resultFor(PrimitiveType actualType, PrimitiveType expectedType,
446 AccessorType actualAccessor,
447 AccessorType expectedAccessor) {
448 return (actualType != expectedType) || (actualAccessor != expectedAccessor);
449 }
450
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
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
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100686 System.out.println("Passed MethodHandle.invokeExact() tests for accessors.");
Orion Hodson3d617ac2016-10-19 14:00:46 +0100687 }
688 }
689
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100690 public static class FindAccessorTester extends Tester {
Orion Hodson3d617ac2016-10-19 14:00:46 +0100691 public static void main() throws Throwable {
Orion Hodson0c14d8b2016-11-03 12:01:24 +0000692 // 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.
Orion Hodson3d617ac2016-10-19 14:00:46 +0100696 MethodHandles.Lookup lookup = MethodHandles.lookup();
Orion Hodson0c14d8b2016-11-03 12:01:24 +0000697 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(); }
Orion Hodson3d617ac2016-10-19 14:00:46 +0100706 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) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100732
733 System.out.println("Passed MethodHandles.Lookup tests for accessors.");
734 }
735 }
736
737 public static class InvokeTester extends Tester {
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) {}
Orion Hodson3d617ac2016-10-19 14:00:46 +0100758 }
759
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100760 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
783 private static void testMemberSetter() throws Throwable {
784 ValueHolder valueHolder = new ValueHolder();
785 MethodHandles.Lookup lookup = MethodHandles.lookup();
786 MethodHandle h0 = lookup.findSetter(ValueHolder.class, "m_f", float.class);
787 h0.invoke(valueHolder, 0.22f);
788 h0.invoke(valueHolder, new Float(1.11f));
789 Number floatNumber = new Float(0.88f);
790 h0.invoke(valueHolder, floatNumber);
791 assertTrue(valueHolder.m_f == floatNumber.floatValue());
792
793 try {
794 h0.invoke(valueHolder, (Float)null);
795 unreachable();
796 } catch (NullPointerException e) {}
797
798 h0.invoke(valueHolder, (byte)1);
799 h0.invoke(valueHolder, (short)2);
800 h0.invoke(valueHolder, 3);
801 h0.invoke(valueHolder, 4l);
802 try {
803 h0.invoke(valueHolder, 0.33);
804 unreachable();
805 } catch (WrongMethodTypeException e) {}
806 try {
807 Number doubleNumber = new Double(0.89);
808 h0.invoke(valueHolder, doubleNumber);
809 unreachable();
810 } catch (ClassCastException e) {}
811 try {
812 Number doubleNumber = null;
813 h0.invoke(valueHolder, doubleNumber);
814 unreachable();
815 } catch (NullPointerException e) {}
816 try {
817 // Mismatched return type - float != void
818 float tmp = (float)h0.invoke(valueHolder, 0.45f);
819 assertTrue(tmp == 0.0);
820 } catch (Exception e) { unreachable(); }
821 try {
822 h0.invoke(valueHolder, "bam");
823 unreachable();
824 } catch (WrongMethodTypeException e) {}
825 try {
826 String s = null;
827 h0.invoke(valueHolder, s);
828 unreachable();
829 } catch (WrongMethodTypeException e) {}
830 }
831
832 private static void testStaticSetter() throws Throwable {
833 MethodHandles.Lookup lookup = MethodHandles.lookup();
834 MethodHandle h0 = lookup.findStaticSetter(ValueHolder.class, "s_f", float.class);
835 h0.invoke(0.22f);
836 h0.invoke(new Float(1.11f));
837 Number floatNumber = new Float(0.88f);
838 h0.invoke(floatNumber);
839 assertTrue(ValueHolder.s_f == floatNumber.floatValue());
840
841 try {
842 h0.invoke((Float)null);
843 unreachable();
844 } catch (NullPointerException e) {}
845
846 h0.invoke((byte)1);
847 h0.invoke((short)2);
848 h0.invoke(3);
849 h0.invoke(4l);
850 try {
851 h0.invoke(0.33);
852 unreachable();
853 } catch (WrongMethodTypeException e) {}
854 try {
855 Number doubleNumber = new Double(0.89);
856 h0.invoke(doubleNumber);
857 unreachable();
858 } catch (ClassCastException e) {}
859 try {
860 Number doubleNumber = new Double(1.01);
861 doubleNumber = (doubleNumber.doubleValue() != 0.1) ? null : doubleNumber;
862 h0.invoke(doubleNumber);
863 unreachable();
864 } catch (NullPointerException e) {}
865 try {
866 // Mismatched return type - float != void
867 float tmp = (float)h0.invoke(0.45f);
868 assertTrue(tmp == 0.0);
869 } catch (Exception e) { unreachable(); }
870 try {
871 h0.invoke("bam");
872 unreachable();
873 } catch (WrongMethodTypeException e) {}
874 try {
875 String s = null;
876 h0.invoke(s);
877 unreachable();
878 } catch (WrongMethodTypeException e) {}
879 }
880
881 public static void main() throws Throwable{
882 testStaticGetter();
883 testMemberGetter();
884 testStaticSetter();
885 testMemberSetter();
886 System.out.println("Passed MethodHandle.invoke() tests for accessors.");
Orion Hodson3d617ac2016-10-19 14:00:46 +0100887 }
888 }
889
890 public static void main(String[] args) throws Throwable {
Orion Hodson0c14d8b2016-11-03 12:01:24 +0000891 // FindAccessor test should be the first test class in this
892 // file to ensure class initialization test is run.
Orion Hodson3d617ac2016-10-19 14:00:46 +0100893 FindAccessorTester.main();
894 InvokeExactTester.main();
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100895 InvokeTester.main();
Orion Hodson3d617ac2016-10-19 14:00:46 +0100896 }
897}