blob: 03fd285d464ff8e957e016ccbbc86f4eaba45bb3 [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;
Orion Hodsonedd706f2017-10-12 14:33:57 +010019import java.lang.reflect.Field;
Orion Hodson3d617ac2016-10-19 14:00:46 +010020
21public class Main {
22
23 public static class ValueHolder {
24 public boolean m_z = false;
25 public byte m_b = 0;
26 public char m_c = 'a';
27 public short m_s = 0;
28 public int m_i = 0;
29 public float m_f = 0.0f;
30 public double m_d = 0.0;
31 public long m_j = 0;
32 public String m_l = "a";
33
34 public static boolean s_z;
35 public static byte s_b;
36 public static char s_c;
37 public static short s_s;
38 public static int s_i;
39 public static float s_f;
40 public static double s_d;
41 public static long s_j;
42 public static String s_l;
43
44 public final int m_fi = 0xa5a5a5a5;
45 public static final int s_fi = 0x5a5a5a5a;
Orion Hodsonedd706f2017-10-12 14:33:57 +010046
47 private boolean m_pz;
48 private static final boolean s_fz = false;
Orion Hodson3d617ac2016-10-19 14:00:46 +010049 }
50
Orion Hodsonba28f9f2016-10-26 10:56:25 +010051 public static class Tester {
Orion Hodson3e0131d2017-10-13 08:56:20 +010052 public static void assertEquals(boolean expected, boolean actual) {
Orion Hodsonba28f9f2016-10-26 10:56:25 +010053 if (actual != expected) {
54 throw new AssertionError("Actual != Expected (" + actual + " != " + expected + ")");
55 }
56 }
57
Orion Hodson3e0131d2017-10-13 08:56:20 +010058 public static void assertEquals(char expected, char actual) {
Orion Hodsonedd706f2017-10-12 14:33:57 +010059 if (actual != expected) {
60 throw new AssertionError("Actual != Expected (" + actual + " != " + expected + ")");
61 }
62 }
63
Orion Hodson3e0131d2017-10-13 08:56:20 +010064 public static void assertEquals(int expected, int actual) {
Orion Hodsonedd706f2017-10-12 14:33:57 +010065 if (actual != expected) {
66 throw new AssertionError("Actual != Expected (" + actual + " != " + expected + ")");
67 }
68 }
69
Orion Hodsonba28f9f2016-10-26 10:56:25 +010070 public static void assertTrue(boolean value) throws AssertionError {
71 if (!value) {
72 throw new AssertionError("Value is not true");
73 }
74 }
75
Orion Hodson3e0131d2017-10-13 08:56:20 +010076 public static void fail() throws Throwable{
77 throw new Error("fail");
Orion Hodsonba28f9f2016-10-26 10:56:25 +010078 }
79 }
80
81 public static class InvokeExactTester extends Tester {
Orion Hodson3d617ac2016-10-19 14:00:46 +010082 private enum PrimitiveType {
83 Boolean,
84 Byte,
85 Char,
86 Short,
87 Int,
88 Long,
89 Float,
90 Double,
91 String,
92 }
93
94 private enum AccessorType {
95 IPUT,
96 SPUT,
97 IGET,
98 SGET,
99 }
100
Orion Hodson3d617ac2016-10-19 14:00:46 +0100101 static void setByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)
102 throws Throwable {
103 boolean exceptionThrown = false;
104 try {
105 if (v == null) {
106 m.invokeExact(value);
107 }
108 else {
109 m.invokeExact(v, value);
110 }
111 }
112 catch (WrongMethodTypeException e) {
113 exceptionThrown = true;
114 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100115 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100116 }
117
118 static void setByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable {
119 setByte(m, null, value, expectFailure);
120 }
121
122 static void getByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)
123 throws Throwable {
124 boolean exceptionThrown = false;
125 try {
126 final byte got;
127 if (v == null) {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100128 got = (byte) m.invokeExact();
Orion Hodson3d617ac2016-10-19 14:00:46 +0100129 } else {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100130 got = (byte) m.invokeExact(v);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100131 }
132 assertTrue(got == value);
133 }
134 catch (WrongMethodTypeException e) {
135 exceptionThrown = true;
136 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100137 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100138 }
139
140 static void getByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable {
141 getByte(m, null, value, expectFailure);
142 }
143
144 static void setChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)
145 throws Throwable {
146 boolean exceptionThrown = false;
147 try {
148 if (v == null) {
149 m.invokeExact(value);
150 }
151 else {
152 m.invokeExact(v, value);
153 }
154 }
155 catch (WrongMethodTypeException e) {
156 exceptionThrown = true;
157 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100158 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100159 }
160
161 static void setChar(MethodHandle m, char value, boolean expectFailure) throws Throwable {
162 setChar(m, null, value, expectFailure);
163 }
164
165 static void getChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)
166 throws Throwable {
167 boolean exceptionThrown = false;
168 try {
169 final char got;
170 if (v == null) {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100171 got = (char) m.invokeExact();
Orion Hodson3d617ac2016-10-19 14:00:46 +0100172 } else {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100173 got = (char) m.invokeExact(v);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100174 }
175 assertTrue(got == value);
176 }
177 catch (WrongMethodTypeException e) {
178 exceptionThrown = true;
179 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100180 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100181 }
182
183 static void getChar(MethodHandle m, char value, boolean expectFailure) throws Throwable {
184 getChar(m, null, value, expectFailure);
185 }
186
187 static void setShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)
188 throws Throwable {
189 boolean exceptionThrown = false;
190 try {
191 if (v == null) {
192 m.invokeExact(value);
193 }
194 else {
195 m.invokeExact(v, value);
196 }
197 }
198 catch (WrongMethodTypeException e) {
199 exceptionThrown = true;
200 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100201 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100202 }
203
204 static void setShort(MethodHandle m, short value, boolean expectFailure) throws Throwable {
205 setShort(m, null, value, expectFailure);
206 }
207
208 static void getShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)
209 throws Throwable {
210 boolean exceptionThrown = false;
211 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100212 final short got = (v == null) ? (short) m.invokeExact() : (short) m.invokeExact(v);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100213 assertTrue(got == value);
214 }
215 catch (WrongMethodTypeException e) {
216 exceptionThrown = true;
217 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100218 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100219 }
220
221 static void getShort(MethodHandle m, short value, boolean expectFailure) throws Throwable {
222 getShort(m, null, value, expectFailure);
223 }
224
225 static void setInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)
226 throws Throwable {
227 boolean exceptionThrown = false;
228 try {
229 if (v == null) {
230 m.invokeExact(value);
231 }
232 else {
233 m.invokeExact(v, value);
234 }
235 }
236 catch (WrongMethodTypeException e) {
237 exceptionThrown = true;
238 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100239 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100240 }
241
242 static void setInt(MethodHandle m, int value, boolean expectFailure) throws Throwable {
243 setInt(m, null, value, expectFailure);
244 }
245
246 static void getInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)
247 throws Throwable {
248 boolean exceptionThrown = false;
249 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100250 final int got = (v == null) ? (int) m.invokeExact() : (int) m.invokeExact(v);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100251 assertTrue(got == value);
252 }
253 catch (WrongMethodTypeException e) {
254 exceptionThrown = true;
255 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100256 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100257 }
258
259 static void getInt(MethodHandle m, int value, boolean expectFailure) throws Throwable {
260 getInt(m, null, value, expectFailure);
261 }
262
263 static void setLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)
264 throws Throwable {
265 boolean exceptionThrown = false;
266 try {
267 if (v == null) {
268 m.invokeExact(value);
269 }
270 else {
271 m.invokeExact(v, value);
272 }
273 }
274 catch (WrongMethodTypeException e) {
275 exceptionThrown = true;
276 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100277 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100278 }
279
280 static void setLong(MethodHandle m, long value, boolean expectFailure) throws Throwable {
281 setLong(m, null, value, expectFailure);
282 }
283
284 static void getLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)
285 throws Throwable {
286 boolean exceptionThrown = false;
287 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100288 final long got = (v == null) ? (long) m.invokeExact() : (long) m.invokeExact(v);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100289 assertTrue(got == value);
290 }
291 catch (WrongMethodTypeException e) {
292 exceptionThrown = true;
293 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100294 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100295 }
296
297 static void getLong(MethodHandle m, long value, boolean expectFailure) throws Throwable {
298 getLong(m, null, value, expectFailure);
299 }
300
301 static void setFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)
302 throws Throwable {
303 boolean exceptionThrown = false;
304 try {
305 if (v == null) {
306 m.invokeExact(value);
307 }
308 else {
309 m.invokeExact(v, value);
310 }
311 }
312 catch (WrongMethodTypeException e) {
313 exceptionThrown = true;
314 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100315 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100316 }
317
318 static void setFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable {
319 setFloat(m, null, value, expectFailure);
320 }
321
322 static void getFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)
323 throws Throwable {
324 boolean exceptionThrown = false;
325 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100326 final float got = (v == null) ? (float) m.invokeExact() : (float) m.invokeExact(v);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100327 assertTrue(got == value);
328 }
329 catch (WrongMethodTypeException e) {
330 exceptionThrown = true;
331 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100332 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100333 }
334
335 static void getFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable {
336 getFloat(m, null, value, expectFailure);
337 }
338
339 static void setDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)
340 throws Throwable {
341 boolean exceptionThrown = false;
342 try {
343 if (v == null) {
344 m.invokeExact(value);
345 }
346 else {
347 m.invokeExact(v, value);
348 }
349 }
350 catch (WrongMethodTypeException e) {
351 exceptionThrown = true;
352 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100353 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100354 }
355
356 static void setDouble(MethodHandle m, double value, boolean expectFailure)
357 throws Throwable {
358 setDouble(m, null, value, expectFailure);
359 }
360
361 static void getDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)
362 throws Throwable {
363 boolean exceptionThrown = false;
364 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100365 final double got = (v == null) ? (double) m.invokeExact() : (double) m.invokeExact(v);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100366 assertTrue(got == value);
367 }
368 catch (WrongMethodTypeException e) {
369 exceptionThrown = true;
370 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100371 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100372 }
373
374 static void getDouble(MethodHandle m, double value, boolean expectFailure)
375 throws Throwable {
376 getDouble(m, null, value, expectFailure);
377 }
378
379 static void setString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)
380 throws Throwable {
381 boolean exceptionThrown = false;
382 try {
383 if (v == null) {
384 m.invokeExact(value);
385 }
386 else {
387 m.invokeExact(v, value);
388 }
389 }
390 catch (WrongMethodTypeException e) {
391 exceptionThrown = true;
392 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100393 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100394 }
395
396 static void setString(MethodHandle m, String value, boolean expectFailure)
397 throws Throwable {
398 setString(m, null, value, expectFailure);
399 }
400
401 static void getString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)
402 throws Throwable {
403 boolean exceptionThrown = false;
404 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100405 final String got = (v == null) ? (String) m.invokeExact() : (String) m.invokeExact(v);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100406 assertTrue(got.equals(value));
407 }
408 catch (WrongMethodTypeException e) {
409 exceptionThrown = true;
410 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100411 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100412 }
413
414 static void getString(MethodHandle m, String value, boolean expectFailure)
415 throws Throwable {
416 getString(m, null, value, expectFailure);
417 }
418
419 static void setBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)
420 throws Throwable {
421 boolean exceptionThrown = false;
422 try {
423 if (v == null) {
424 m.invokeExact(value);
425 }
426 else {
427 m.invokeExact(v, value);
428 }
429 }
430 catch (WrongMethodTypeException e) {
431 exceptionThrown = true;
432 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100433 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100434 }
435
436 static void setBoolean(MethodHandle m, boolean value, boolean expectFailure)
437 throws Throwable {
438 setBoolean(m, null, value, expectFailure);
439 }
440
441 static void getBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)
442 throws Throwable {
443 boolean exceptionThrown = false;
444 try {
445 final boolean got =
Orion Hodson3e0131d2017-10-13 08:56:20 +0100446 (v == null) ? (boolean) m.invokeExact() : (boolean) m.invokeExact(v);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100447 assertTrue(got == value);
448 }
449 catch (WrongMethodTypeException e) {
450 exceptionThrown = true;
451 }
Orion Hodson3e0131d2017-10-13 08:56:20 +0100452 assertEquals(expectFailure, exceptionThrown);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100453 }
454
455 static void getBoolean(MethodHandle m, boolean value, boolean expectFailure)
456 throws Throwable {
457 getBoolean(m, null, value, expectFailure);
458 }
459
460 static boolean resultFor(PrimitiveType actualType, PrimitiveType expectedType,
461 AccessorType actualAccessor,
462 AccessorType expectedAccessor) {
463 return (actualType != expectedType) || (actualAccessor != expectedAccessor);
464 }
465
466 static void tryAccessor(MethodHandle methodHandle,
467 ValueHolder valueHolder,
468 PrimitiveType primitive,
469 Object value,
470 AccessorType accessor) throws Throwable {
471 boolean booleanValue =
Orion Hodson3e0131d2017-10-13 08:56:20 +0100472 value instanceof Boolean ? ((Boolean) value).booleanValue() : false;
Orion Hodson3d617ac2016-10-19 14:00:46 +0100473 setBoolean(methodHandle, valueHolder, booleanValue,
474 resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.IPUT));
475 setBoolean(methodHandle, booleanValue,
476 resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.SPUT));
477 getBoolean(methodHandle, valueHolder, booleanValue,
478 resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.IGET));
479 getBoolean(methodHandle, booleanValue,
480 resultFor(primitive, PrimitiveType.Boolean, accessor, AccessorType.SGET));
481
Orion Hodson3e0131d2017-10-13 08:56:20 +0100482 byte byteValue = value instanceof Byte ? ((Byte) value).byteValue() : (byte) 0;
Orion Hodson3d617ac2016-10-19 14:00:46 +0100483 setByte(methodHandle, valueHolder, byteValue,
484 resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.IPUT));
485 setByte(methodHandle, byteValue,
486 resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.SPUT));
487 getByte(methodHandle, valueHolder, byteValue,
488 resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.IGET));
489 getByte(methodHandle, byteValue,
490 resultFor(primitive, PrimitiveType.Byte, accessor, AccessorType.SGET));
491
Orion Hodson3e0131d2017-10-13 08:56:20 +0100492 char charValue = value instanceof Character ? ((Character) value).charValue() : 'z';
Orion Hodson3d617ac2016-10-19 14:00:46 +0100493 setChar(methodHandle, valueHolder, charValue,
494 resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.IPUT));
495 setChar(methodHandle, charValue,
496 resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.SPUT));
497 getChar(methodHandle, valueHolder, charValue,
498 resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.IGET));
499 getChar(methodHandle, charValue,
500 resultFor(primitive, PrimitiveType.Char, accessor, AccessorType.SGET));
501
Orion Hodson3e0131d2017-10-13 08:56:20 +0100502 short shortValue = value instanceof Short ? ((Short) value).shortValue() : (short) 0;
Orion Hodson3d617ac2016-10-19 14:00:46 +0100503 setShort(methodHandle, valueHolder, shortValue,
504 resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.IPUT));
505 setShort(methodHandle, shortValue,
506 resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.SPUT));
507 getShort(methodHandle, valueHolder, shortValue,
508 resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.IGET));
509 getShort(methodHandle, shortValue,
510 resultFor(primitive, PrimitiveType.Short, accessor, AccessorType.SGET));
511
Orion Hodson3e0131d2017-10-13 08:56:20 +0100512 int intValue = value instanceof Integer ? ((Integer) value).intValue() : -1;
Orion Hodson3d617ac2016-10-19 14:00:46 +0100513 setInt(methodHandle, valueHolder, intValue,
514 resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.IPUT));
515 setInt(methodHandle, intValue,
516 resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.SPUT));
517 getInt(methodHandle, valueHolder, intValue,
518 resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.IGET));
519 getInt(methodHandle, intValue,
520 resultFor(primitive, PrimitiveType.Int, accessor, AccessorType.SGET));
521
Orion Hodson3e0131d2017-10-13 08:56:20 +0100522 long longValue = value instanceof Long ? ((Long) value).longValue() : (long) -1;
Orion Hodson3d617ac2016-10-19 14:00:46 +0100523 setLong(methodHandle, valueHolder, longValue,
524 resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.IPUT));
525 setLong(methodHandle, longValue,
526 resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.SPUT));
527 getLong(methodHandle, valueHolder, longValue,
528 resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.IGET));
529 getLong(methodHandle, longValue,
530 resultFor(primitive, PrimitiveType.Long, accessor, AccessorType.SGET));
531
Orion Hodson3e0131d2017-10-13 08:56:20 +0100532 float floatValue = value instanceof Float ? ((Float) value).floatValue() : -1.0f;
Orion Hodson3d617ac2016-10-19 14:00:46 +0100533 setFloat(methodHandle, valueHolder, floatValue,
534 resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.IPUT));
535 setFloat(methodHandle, floatValue,
536 resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.SPUT));
537 getFloat(methodHandle, valueHolder, floatValue,
538 resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.IGET));
539 getFloat(methodHandle, floatValue,
540 resultFor(primitive, PrimitiveType.Float, accessor, AccessorType.SGET));
541
Orion Hodson3e0131d2017-10-13 08:56:20 +0100542 double doubleValue = value instanceof Double ? ((Double) value).doubleValue() : -1.0;
Orion Hodson3d617ac2016-10-19 14:00:46 +0100543 setDouble(methodHandle, valueHolder, doubleValue,
544 resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.IPUT));
545 setDouble(methodHandle, doubleValue,
546 resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.SPUT));
547 getDouble(methodHandle, valueHolder, doubleValue,
548 resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.IGET));
549 getDouble(methodHandle, doubleValue,
550 resultFor(primitive, PrimitiveType.Double, accessor, AccessorType.SGET));
551
552 String stringValue = value instanceof String ? ((String) value) : "No Spock, no";
553 setString(methodHandle, valueHolder, stringValue,
554 resultFor(primitive, PrimitiveType.String, accessor, AccessorType.IPUT));
555 setString(methodHandle, stringValue,
556 resultFor(primitive, PrimitiveType.String, accessor, AccessorType.SPUT));
557 getString(methodHandle, valueHolder, stringValue,
558 resultFor(primitive, PrimitiveType.String, accessor, AccessorType.IGET));
559 getString(methodHandle, stringValue,
560 resultFor(primitive, PrimitiveType.String, accessor, AccessorType.SGET));
561 }
562
563 public static void main() throws Throwable {
564 ValueHolder valueHolder = new ValueHolder();
565 MethodHandles.Lookup lookup = MethodHandles.lookup();
566
567 boolean [] booleans = { false, true, false };
568 for (boolean b : booleans) {
569 Boolean boxed = new Boolean(b);
570 tryAccessor(lookup.findSetter(ValueHolder.class, "m_z", boolean.class),
571 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.IPUT);
572 tryAccessor(lookup.findGetter(ValueHolder.class, "m_z", boolean.class),
573 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.IGET);
574 assertTrue(valueHolder.m_z == b);
575 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_z", boolean.class),
576 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.SPUT);
577 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_z", boolean.class),
578 valueHolder, PrimitiveType.Boolean, boxed, AccessorType.SGET);
579 assertTrue(ValueHolder.s_z == b);
580 }
581
Orion Hodson3e0131d2017-10-13 08:56:20 +0100582 byte [] bytes = { (byte) 0x73, (byte) 0xfe };
Orion Hodson3d617ac2016-10-19 14:00:46 +0100583 for (byte b : bytes) {
584 Byte boxed = new Byte(b);
585 tryAccessor(lookup.findSetter(ValueHolder.class, "m_b", byte.class),
586 valueHolder, PrimitiveType.Byte, boxed, AccessorType.IPUT);
587 tryAccessor(lookup.findGetter(ValueHolder.class, "m_b", byte.class),
588 valueHolder, PrimitiveType.Byte, boxed, AccessorType.IGET);
589 assertTrue(valueHolder.m_b == b);
590 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_b", byte.class),
591 valueHolder, PrimitiveType.Byte, boxed, AccessorType.SPUT);
592 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_b", byte.class),
593 valueHolder, PrimitiveType.Byte, boxed, AccessorType.SGET);
594 assertTrue(ValueHolder.s_b == b);
595 }
596
597 char [] chars = { 'a', 'b', 'c' };
598 for (char c : chars) {
599 Character boxed = new Character(c);
600 tryAccessor(lookup.findSetter(ValueHolder.class, "m_c", char.class),
601 valueHolder, PrimitiveType.Char, boxed, AccessorType.IPUT);
602 tryAccessor(lookup.findGetter(ValueHolder.class, "m_c", char.class),
603 valueHolder, PrimitiveType.Char, boxed, AccessorType.IGET);
604 assertTrue(valueHolder.m_c == c);
605 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_c", char.class),
606 valueHolder, PrimitiveType.Char, boxed, AccessorType.SPUT);
607 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_c", char.class),
608 valueHolder, PrimitiveType.Char, boxed, AccessorType.SGET);
609 assertTrue(ValueHolder.s_c == c);
610 }
611
Orion Hodson3e0131d2017-10-13 08:56:20 +0100612 short [] shorts = { (short) 0x1234, (short) 0x4321 };
Orion Hodson3d617ac2016-10-19 14:00:46 +0100613 for (short s : shorts) {
614 Short boxed = new Short(s);
615 tryAccessor(lookup.findSetter(ValueHolder.class, "m_s", short.class),
616 valueHolder, PrimitiveType.Short, boxed, AccessorType.IPUT);
617 tryAccessor(lookup.findGetter(ValueHolder.class, "m_s", short.class),
618 valueHolder, PrimitiveType.Short, boxed, AccessorType.IGET);
619 assertTrue(valueHolder.m_s == s);
620 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_s", short.class),
621 valueHolder, PrimitiveType.Short, boxed, AccessorType.SPUT);
622 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_s", short.class),
623 valueHolder, PrimitiveType.Short, boxed, AccessorType.SGET);
624 assertTrue(ValueHolder.s_s == s);
625 }
626
627 int [] ints = { -100000000, 10000000 };
628 for (int i : ints) {
629 Integer boxed = new Integer(i);
630 tryAccessor(lookup.findSetter(ValueHolder.class, "m_i", int.class),
631 valueHolder, PrimitiveType.Int, boxed, AccessorType.IPUT);
632 tryAccessor(lookup.findGetter(ValueHolder.class, "m_i", int.class),
633 valueHolder, PrimitiveType.Int, boxed, AccessorType.IGET);
634 assertTrue(valueHolder.m_i == i);
635 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_i", int.class),
636 valueHolder, PrimitiveType.Int, boxed, AccessorType.SPUT);
637 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_i", int.class),
638 valueHolder, PrimitiveType.Int, boxed, AccessorType.SGET);
639 assertTrue(ValueHolder.s_i == i);
640 }
641
642 float [] floats = { 0.99f, -1.23e-17f };
643 for (float f : floats) {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100644 Float boxed = Float.valueOf(f);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100645 tryAccessor(lookup.findSetter(ValueHolder.class, "m_f", float.class),
646 valueHolder, PrimitiveType.Float, boxed, AccessorType.IPUT);
647 tryAccessor(lookup.findGetter(ValueHolder.class, "m_f", float.class),
648 valueHolder, PrimitiveType.Float, boxed, AccessorType.IGET);
649 assertTrue(valueHolder.m_f == f);
650 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_f", float.class),
651 valueHolder, PrimitiveType.Float, boxed, AccessorType.SPUT);
652 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_f", float.class),
653 valueHolder, PrimitiveType.Float, boxed, AccessorType.SGET);
654 assertTrue(ValueHolder.s_f == f);
655 }
656
657 double [] doubles = { 0.44444444444e37, -0.555555555e-37 };
658 for (double d : doubles) {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100659 Double boxed = Double.valueOf(d);
Orion Hodson3d617ac2016-10-19 14:00:46 +0100660 tryAccessor(lookup.findSetter(ValueHolder.class, "m_d", double.class),
661 valueHolder, PrimitiveType.Double, boxed, AccessorType.IPUT);
662 tryAccessor(lookup.findGetter(ValueHolder.class, "m_d", double.class),
663 valueHolder, PrimitiveType.Double, boxed, AccessorType.IGET);
664 assertTrue(valueHolder.m_d == d);
665 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_d", double.class),
666 valueHolder, PrimitiveType.Double, boxed, AccessorType.SPUT);
667 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_d", double.class),
668 valueHolder, PrimitiveType.Double, boxed, AccessorType.SGET);
669 assertTrue(ValueHolder.s_d == d);
670 }
671
672 long [] longs = { 0x0123456789abcdefl, 0xfedcba9876543210l };
673 for (long j : longs) {
674 Long boxed = new Long(j);
675 tryAccessor(lookup.findSetter(ValueHolder.class, "m_j", long.class),
676 valueHolder, PrimitiveType.Long, boxed, AccessorType.IPUT);
677 tryAccessor(lookup.findGetter(ValueHolder.class, "m_j", long.class),
678 valueHolder, PrimitiveType.Long, boxed, AccessorType.IGET);
679 assertTrue(valueHolder.m_j == j);
680 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_j", long.class),
681 valueHolder, PrimitiveType.Long, boxed, AccessorType.SPUT);
682 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_j", long.class),
683 valueHolder, PrimitiveType.Long, boxed, AccessorType.SGET);
684 assertTrue(ValueHolder.s_j == j);
685 }
686
687 String [] strings = { "octopus", "crab" };
688 for (String s : strings) {
689 tryAccessor(lookup.findSetter(ValueHolder.class, "m_l", String.class),
690 valueHolder, PrimitiveType.String, s, AccessorType.IPUT);
691 tryAccessor(lookup.findGetter(ValueHolder.class, "m_l", String.class),
692 valueHolder, PrimitiveType.String, s, AccessorType.IGET);
693 assertTrue(s.equals(valueHolder.m_l));
694 tryAccessor(lookup.findStaticSetter(ValueHolder.class, "s_l", String.class),
695 valueHolder, PrimitiveType.String, s, AccessorType.SPUT);
696 tryAccessor(lookup.findStaticGetter(ValueHolder.class, "s_l", String.class),
697 valueHolder, PrimitiveType.String, s, AccessorType.SGET);
698 assertTrue(s.equals(ValueHolder.s_l));
699 }
700
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100701 System.out.println("Passed MethodHandle.invokeExact() tests for accessors.");
Orion Hodson3d617ac2016-10-19 14:00:46 +0100702 }
703 }
704
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100705 public static class FindAccessorTester extends Tester {
Orion Hodson3d617ac2016-10-19 14:00:46 +0100706 public static void main() throws Throwable {
Orion Hodson0c14d8b2016-11-03 12:01:24 +0000707 // NB having a static field test here is essential for
708 // this test. MethodHandles need to ensure the class
709 // (ValueHolder) is initialized. This happens in the
710 // invoke-polymorphic dispatch.
Orion Hodson3d617ac2016-10-19 14:00:46 +0100711 MethodHandles.Lookup lookup = MethodHandles.lookup();
Orion Hodsonedd706f2017-10-12 14:33:57 +0100712 {
Orion Hodson0c14d8b2016-11-03 12:01:24 +0000713 MethodHandle mh = lookup.findStaticGetter(ValueHolder.class, "s_fi", int.class);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100714 int initialValue = (int) mh.invokeExact();
Orion Hodson0c14d8b2016-11-03 12:01:24 +0000715 System.out.println(initialValue);
Orion Hodsonedd706f2017-10-12 14:33:57 +0100716 }
717 {
Orion Hodson0c14d8b2016-11-03 12:01:24 +0000718 MethodHandle mh = lookup.findStaticSetter(ValueHolder.class, "s_i", int.class);
719 mh.invokeExact(0);
Orion Hodsonedd706f2017-10-12 14:33:57 +0100720 }
Orion Hodson3d617ac2016-10-19 14:00:46 +0100721 try {
722 lookup.findStaticGetter(ValueHolder.class, "s_fi", byte.class);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100723 fail();
724 } catch (NoSuchFieldException expected) {}
Orion Hodson3d617ac2016-10-19 14:00:46 +0100725 try {
726 lookup.findGetter(ValueHolder.class, "s_fi", byte.class);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100727 fail();
728 } catch (NoSuchFieldException eexpected) {}
Orion Hodson3d617ac2016-10-19 14:00:46 +0100729 try {
730 lookup.findStaticSetter(ValueHolder.class, "s_fi", int.class);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100731 fail();
732 } catch (IllegalAccessException expected) {}
Orion Hodson3d617ac2016-10-19 14:00:46 +0100733
734 lookup.findGetter(ValueHolder.class, "m_fi", int.class);
735 try {
736 lookup.findGetter(ValueHolder.class, "m_fi", byte.class);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100737 fail();
738 } catch (NoSuchFieldException expected) {}
Orion Hodson3d617ac2016-10-19 14:00:46 +0100739 try {
740 lookup.findStaticGetter(ValueHolder.class, "m_fi", byte.class);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100741 fail();
742 } catch (NoSuchFieldException expected) {}
Orion Hodson3d617ac2016-10-19 14:00:46 +0100743 try {
744 lookup.findSetter(ValueHolder.class, "m_fi", int.class);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100745 fail();
746 } catch (IllegalAccessException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100747
748 System.out.println("Passed MethodHandles.Lookup tests for accessors.");
749 }
750 }
751
752 public static class InvokeTester extends Tester {
753 private static void testStaticGetter() throws Throwable {
754 MethodHandles.Lookup lookup = MethodHandles.lookup();
755 MethodHandle h0 = lookup.findStaticGetter(ValueHolder.class, "s_fi", int.class);
756 h0.invoke();
Orion Hodson3e0131d2017-10-13 08:56:20 +0100757 Number t = (Number) h0.invoke();
758 int u = (int) h0.invoke();
759 Integer v = (Integer) h0.invoke();
760 long w = (long) h0.invoke();
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100761 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100762 byte x = (byte) h0.invoke();
763 fail();
764 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100765 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100766 String y = (String) h0.invoke();
767 fail();
768 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100769 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100770 Long z = (Long) h0.invoke();
771 fail();
772 } catch (WrongMethodTypeException expected) {}
Orion Hodson3d617ac2016-10-19 14:00:46 +0100773 }
774
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100775 private static void testMemberGetter() throws Throwable {
776 ValueHolder valueHolder = new ValueHolder();
777 MethodHandles.Lookup lookup = MethodHandles.lookup();
778 MethodHandle h0 = lookup.findGetter(ValueHolder.class, "m_fi", int.class);
779 h0.invoke(valueHolder);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100780 Number t = (Number) h0.invoke(valueHolder);
781 int u = (int) h0.invoke(valueHolder);
782 Integer v = (Integer) h0.invoke(valueHolder);
783 long w = (long) h0.invoke(valueHolder);
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100784 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100785 byte x = (byte) h0.invoke(valueHolder);
786 fail();
787 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100788 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100789 String y = (String) h0.invoke(valueHolder);
790 fail();
791 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100792 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100793 Long z = (Long) h0.invoke(valueHolder);
794 fail();
795 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100796 }
797
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000798 /*package*/ static Number getDoubleAsNumber() {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100799 return Double.valueOf(1.4e77);
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000800 }
801 /*package*/ static Number getFloatAsNumber() {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100802 return Float.valueOf(7.77f);
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000803 }
804 /*package*/ static Object getFloatAsObject() {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100805 return Float.valueOf(-7.77f);
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000806 }
807
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100808 private static void testMemberSetter() throws Throwable {
809 ValueHolder valueHolder = new ValueHolder();
810 MethodHandles.Lookup lookup = MethodHandles.lookup();
811 MethodHandle h0 = lookup.findSetter(ValueHolder.class, "m_f", float.class);
Mathieu Chartier71b17082017-04-17 20:12:29 -0700812 MethodHandle s0 = lookup.findSetter(ValueHolder.class, "m_s", short.class);
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100813 h0.invoke(valueHolder, 0.22f);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100814 h0.invoke(valueHolder, Float.valueOf(1.11f));
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000815 Number floatNumber = getFloatAsNumber();
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100816 h0.invoke(valueHolder, floatNumber);
817 assertTrue(valueHolder.m_f == floatNumber.floatValue());
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000818 Object objNumber = getFloatAsObject();
819 h0.invoke(valueHolder, objNumber);
820 assertTrue(valueHolder.m_f == ((Float) objNumber).floatValue());
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100821 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100822 h0.invoke(valueHolder, (Float) null);
823 fail();
824 } catch (NullPointerException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100825
Mathieu Chartier71b17082017-04-17 20:12:29 -0700826 // Test that type conversion checks work on small field types.
Orion Hodson3e0131d2017-10-13 08:56:20 +0100827 short temp = (short) s0.invoke(valueHolder, new Byte((byte) 45));
Mathieu Chartier71b17082017-04-17 20:12:29 -0700828 assertTrue(temp == 0);
829 assertTrue(valueHolder.m_s == 45);
830
Orion Hodson3e0131d2017-10-13 08:56:20 +0100831 h0.invoke(valueHolder, (byte) 1);
832 h0.invoke(valueHolder, (short) 2);
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100833 h0.invoke(valueHolder, 3);
834 h0.invoke(valueHolder, 4l);
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000835
836 assertTrue(null == (Object) h0.invoke(valueHolder, 33));
837 assertTrue(0.0f == (float) h0.invoke(valueHolder, 33));
838 assertTrue(0l == (long) h0.invoke(valueHolder, 33));
839
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100840 try {
841 h0.invoke(valueHolder, 0.33);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100842 fail();
843 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100844 try {
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000845 Number doubleNumber = getDoubleAsNumber();
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100846 h0.invoke(valueHolder, doubleNumber);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100847 fail();
848 } catch (ClassCastException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100849 try {
850 Number doubleNumber = null;
851 h0.invoke(valueHolder, doubleNumber);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100852 fail();
853 } catch (NullPointerException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +0100854 {
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100855 // Mismatched return type - float != void
Orion Hodson3e0131d2017-10-13 08:56:20 +0100856 float tmp = (float) h0.invoke(valueHolder, 0.45f);
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100857 assertTrue(tmp == 0.0);
Orion Hodsonedd706f2017-10-12 14:33:57 +0100858 }
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100859 try {
860 h0.invoke(valueHolder, "bam");
Orion Hodson3e0131d2017-10-13 08:56:20 +0100861 fail();
862 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100863 try {
864 String s = null;
865 h0.invoke(valueHolder, s);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100866 fail();
867 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100868 }
869
870 private static void testStaticSetter() throws Throwable {
871 MethodHandles.Lookup lookup = MethodHandles.lookup();
Mathieu Chartier71b17082017-04-17 20:12:29 -0700872 MethodHandle s0 = lookup.findStaticSetter(ValueHolder.class, "s_s", short.class);
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100873 MethodHandle h0 = lookup.findStaticSetter(ValueHolder.class, "s_f", float.class);
874 h0.invoke(0.22f);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100875 h0.invoke(Float.valueOf(1.11f));
876 Number floatNumber = Float.valueOf(0.88f);
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100877 h0.invoke(floatNumber);
878 assertTrue(ValueHolder.s_f == floatNumber.floatValue());
879
880 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100881 h0.invoke((Float) null);
882 fail();
883 } catch (NullPointerException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100884
Mathieu Chartier71b17082017-04-17 20:12:29 -0700885 // Test that type conversion checks work on small field types.
Orion Hodson3e0131d2017-10-13 08:56:20 +0100886 short temp = (short) s0.invoke(new Byte((byte) 45));
Mathieu Chartier71b17082017-04-17 20:12:29 -0700887 assertTrue(temp == 0);
888 assertTrue(ValueHolder.s_s == 45);
889
Orion Hodson3e0131d2017-10-13 08:56:20 +0100890 h0.invoke((byte) 1);
891 h0.invoke((short) 2);
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100892 h0.invoke(3);
893 h0.invoke(4l);
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000894
895 assertTrue(null == (Object) h0.invoke(33));
896 assertTrue(0.0f == (float) h0.invoke(33));
897 assertTrue(0l == (long) h0.invoke(33));
898
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100899 try {
900 h0.invoke(0.33);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100901 fail();
902 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100903 try {
Orion Hodsonc1d3bac2018-01-26 14:38:55 +0000904 h0.invoke(Double.valueOf(0.33));
905 fail();
906 } catch (WrongMethodTypeException expected) {}
907 try {
Orion Hodson1a06f9f2016-11-09 08:32:42 +0000908 Number doubleNumber = getDoubleAsNumber();
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100909 h0.invoke(doubleNumber);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100910 fail();
911 } catch (ClassCastException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100912 try {
Orion Hodson3e0131d2017-10-13 08:56:20 +0100913 Number doubleNumber = Double.valueOf(1.01);
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100914 doubleNumber = (doubleNumber.doubleValue() != 0.1) ? null : doubleNumber;
915 h0.invoke(doubleNumber);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100916 fail();
917 } catch (NullPointerException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100918 try {
919 // Mismatched return type - float != void
Orion Hodson3e0131d2017-10-13 08:56:20 +0100920 float tmp = (float) h0.invoke(0.45f);
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100921 assertTrue(tmp == 0.0);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100922 } catch (Exception e) { fail(); }
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100923 try {
924 h0.invoke("bam");
Orion Hodson3e0131d2017-10-13 08:56:20 +0100925 fail();
926 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100927 try {
928 String s = null;
929 h0.invoke(s);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100930 fail();
931 } catch (WrongMethodTypeException expected) {}
Orion Hodsonba28f9f2016-10-26 10:56:25 +0100932 }
933
934 public static void main() throws Throwable{
935 testStaticGetter();
936 testMemberGetter();
937 testStaticSetter();
938 testMemberSetter();
939 System.out.println("Passed MethodHandle.invoke() tests for accessors.");
Orion Hodson3d617ac2016-10-19 14:00:46 +0100940 }
941 }
942
Orion Hodsonedd706f2017-10-12 14:33:57 +0100943 public static class UnreflectTester extends Tester {
944 public static void main() throws Throwable {
945 ValueHolder v = new ValueHolder();
946 {
947 // public field test
948 Field f = ValueHolder.class.getDeclaredField("m_c");
949 MethodHandles.lookup().unreflectSetter(f).invokeExact(v, 'z');
Orion Hodson3e0131d2017-10-13 08:56:20 +0100950 assertEquals('z', (char) MethodHandles.lookup().unreflectGetter(f).invokeExact(v));
Orion Hodsonedd706f2017-10-12 14:33:57 +0100951 MethodHandles.lookup().unreflectSetter(f).invokeExact(v, 'A');
Orion Hodson3e0131d2017-10-13 08:56:20 +0100952 assertEquals('A', (char) MethodHandles.lookup().unreflectGetter(f).invokeExact(v));
Orion Hodsonedd706f2017-10-12 14:33:57 +0100953 }
954 {
955 // public static final field test
956 Field f = ValueHolder.class.getDeclaredField("s_fi");
957 try {
958 MethodHandles.lookup().unreflectSetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100959 fail();
960 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +0100961 MethodHandles.lookup().unreflectGetter(f);
962 f.setAccessible(true);
963 int savedValue = (int) MethodHandles.lookup().unreflectGetter(f).invokeExact();
964 int newValue = savedValue + 1;
965 MethodHandles.lookup().unreflectSetter(f).invokeExact(newValue);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100966 assertEquals(newValue, (int) MethodHandles.lookup().unreflectGetter(f).invokeExact()
967 );
Orion Hodsonedd706f2017-10-12 14:33:57 +0100968 MethodHandles.lookup().unreflectSetter(f).invokeExact(savedValue);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100969 assertEquals(savedValue, (int) MethodHandles.lookup().unreflectGetter(f).invokeExact()
970 );
Orion Hodsonedd706f2017-10-12 14:33:57 +0100971 f.setAccessible(false);
972 try {
973 MethodHandles.lookup().unreflectSetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100974 fail();
975 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +0100976 MethodHandles.lookup().unreflectGetter(f);
977 }
978 {
979 // private field test
980 Field f = ValueHolder.class.getDeclaredField("m_pz");
981 try {
982 MethodHandle mh = MethodHandles.lookup().unreflectSetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100983 fail();
984 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +0100985 try {
986 MethodHandle mh = MethodHandles.lookup().unreflectGetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100987 fail();
988 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +0100989 f.setAccessible(true);
990 MethodHandles.lookup().unreflectSetter(f).invokeExact(v, true);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100991 assertEquals(true, (boolean) MethodHandles.lookup().unreflectGetter(f).invokeExact(v)
992 );
Orion Hodsonedd706f2017-10-12 14:33:57 +0100993 MethodHandles.lookup().unreflectSetter(f).invokeExact(v, false);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100994 assertEquals(false, (boolean) MethodHandles.lookup().unreflectGetter(f).invokeExact(v)
995 );
Orion Hodsonedd706f2017-10-12 14:33:57 +0100996 f.setAccessible(false);
997 try {
998 MethodHandle mh = MethodHandles.lookup().unreflectGetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +0100999 fail();
1000 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +01001001 try {
1002 MethodHandle mh = MethodHandles.lookup().unreflectSetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +01001003 fail();
1004 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +01001005 }
1006 {
1007 // private static final field test
1008 Field f = ValueHolder.class.getDeclaredField("s_fz"); // private static final field
1009 try {
1010 MethodHandles.lookup().unreflectSetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +01001011 fail();
1012 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +01001013 try {
1014 MethodHandles.lookup().unreflectGetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +01001015 fail();
1016 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +01001017 f.setAccessible(true);
1018 // Setter is okay despite being final because field isAccessible().
1019 MethodHandles.lookup().unreflectSetter(f).invokeExact(false);
Orion Hodson3e0131d2017-10-13 08:56:20 +01001020 assertEquals(false, (boolean) MethodHandles.lookup().unreflectGetter(f).invokeExact()
1021 );
Orion Hodsonedd706f2017-10-12 14:33:57 +01001022 MethodHandles.lookup().unreflectSetter(f).invokeExact(true);
Orion Hodson3e0131d2017-10-13 08:56:20 +01001023 assertEquals(true, (boolean) MethodHandles.lookup().unreflectGetter(f).invokeExact()
1024 );
Orion Hodsonedd706f2017-10-12 14:33:57 +01001025 f.setAccessible(false);
1026 try {
1027 MethodHandles.lookup().unreflectSetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +01001028 fail();
1029 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +01001030 try {
1031 MethodHandles.lookup().unreflectGetter(f);
Orion Hodson3e0131d2017-10-13 08:56:20 +01001032 fail();
1033 } catch (IllegalAccessException expected) {}
Orion Hodsonedd706f2017-10-12 14:33:57 +01001034 }
1035 System.out.println("Passed MethodHandles.unreflect(Field) tests.");
1036 }
1037 }
1038
Orion Hodson3d617ac2016-10-19 14:00:46 +01001039 public static void main(String[] args) throws Throwable {
Orion Hodson0c14d8b2016-11-03 12:01:24 +00001040 // FindAccessor test should be the first test class in this
1041 // file to ensure class initialization test is run.
Orion Hodson3d617ac2016-10-19 14:00:46 +01001042 FindAccessorTester.main();
1043 InvokeExactTester.main();
Orion Hodsonba28f9f2016-10-26 10:56:25 +01001044 InvokeTester.main();
Orion Hodsonedd706f2017-10-12 14:33:57 +01001045 UnreflectTester.main();
Orion Hodson3d617ac2016-10-19 14:00:46 +01001046 }
1047}