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 import java.lang.reflect.Field; 20 21 public 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; 46 47 private boolean m_pz; 48 private static final boolean s_fz = false; 49 } 50 51 public static class Tester { assertEquals(boolean expected, boolean actual)52 public static void assertEquals(boolean expected, boolean actual) { 53 if (actual != expected) { 54 throw new AssertionError("Actual != Expected (" + actual + " != " + expected + ")"); 55 } 56 } 57 assertEquals(char expected, char actual)58 public static void assertEquals(char expected, char actual) { 59 if (actual != expected) { 60 throw new AssertionError("Actual != Expected (" + actual + " != " + expected + ")"); 61 } 62 } 63 assertEquals(int expected, int actual)64 public static void assertEquals(int expected, int actual) { 65 if (actual != expected) { 66 throw new AssertionError("Actual != Expected (" + actual + " != " + expected + ")"); 67 } 68 } 69 assertTrue(boolean value)70 public static void assertTrue(boolean value) throws AssertionError { 71 if (!value) { 72 throw new AssertionError("Value is not true"); 73 } 74 } 75 fail()76 public static void fail() throws Throwable{ 77 throw new Error("fail"); 78 } 79 } 80 81 public static class InvokeExactTester extends Tester { 82 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 setByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)101 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 } 115 assertEquals(expectFailure, exceptionThrown); 116 } 117 setByte(MethodHandle m, byte value, boolean expectFailure)118 static void setByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable { 119 setByte(m, null, value, expectFailure); 120 } 121 getByte(MethodHandle m, ValueHolder v, byte value, boolean expectFailure)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) { 128 got = (byte) m.invokeExact(); 129 } else { 130 got = (byte) m.invokeExact(v); 131 } 132 assertTrue(got == value); 133 } 134 catch (WrongMethodTypeException e) { 135 exceptionThrown = true; 136 } 137 assertEquals(expectFailure, exceptionThrown); 138 } 139 getByte(MethodHandle m, byte value, boolean expectFailure)140 static void getByte(MethodHandle m, byte value, boolean expectFailure) throws Throwable { 141 getByte(m, null, value, expectFailure); 142 } 143 setChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)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 } 158 assertEquals(expectFailure, exceptionThrown); 159 } 160 setChar(MethodHandle m, char value, boolean expectFailure)161 static void setChar(MethodHandle m, char value, boolean expectFailure) throws Throwable { 162 setChar(m, null, value, expectFailure); 163 } 164 getChar(MethodHandle m, ValueHolder v, char value, boolean expectFailure)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) { 171 got = (char) m.invokeExact(); 172 } else { 173 got = (char) m.invokeExact(v); 174 } 175 assertTrue(got == value); 176 } 177 catch (WrongMethodTypeException e) { 178 exceptionThrown = true; 179 } 180 assertEquals(expectFailure, exceptionThrown); 181 } 182 getChar(MethodHandle m, char value, boolean expectFailure)183 static void getChar(MethodHandle m, char value, boolean expectFailure) throws Throwable { 184 getChar(m, null, value, expectFailure); 185 } 186 setShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)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 } 201 assertEquals(expectFailure, exceptionThrown); 202 } 203 setShort(MethodHandle m, short value, boolean expectFailure)204 static void setShort(MethodHandle m, short value, boolean expectFailure) throws Throwable { 205 setShort(m, null, value, expectFailure); 206 } 207 getShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure)208 static void getShort(MethodHandle m, ValueHolder v, short value, boolean expectFailure) 209 throws Throwable { 210 boolean exceptionThrown = false; 211 try { 212 final short got = (v == null) ? (short) m.invokeExact() : (short) m.invokeExact(v); 213 assertTrue(got == value); 214 } 215 catch (WrongMethodTypeException e) { 216 exceptionThrown = true; 217 } 218 assertEquals(expectFailure, exceptionThrown); 219 } 220 getShort(MethodHandle m, short value, boolean expectFailure)221 static void getShort(MethodHandle m, short value, boolean expectFailure) throws Throwable { 222 getShort(m, null, value, expectFailure); 223 } 224 setInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)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 } 239 assertEquals(expectFailure, exceptionThrown); 240 } 241 setInt(MethodHandle m, int value, boolean expectFailure)242 static void setInt(MethodHandle m, int value, boolean expectFailure) throws Throwable { 243 setInt(m, null, value, expectFailure); 244 } 245 getInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure)246 static void getInt(MethodHandle m, ValueHolder v, int value, boolean expectFailure) 247 throws Throwable { 248 boolean exceptionThrown = false; 249 try { 250 final int got = (v == null) ? (int) m.invokeExact() : (int) m.invokeExact(v); 251 assertTrue(got == value); 252 } 253 catch (WrongMethodTypeException e) { 254 exceptionThrown = true; 255 } 256 assertEquals(expectFailure, exceptionThrown); 257 } 258 getInt(MethodHandle m, int value, boolean expectFailure)259 static void getInt(MethodHandle m, int value, boolean expectFailure) throws Throwable { 260 getInt(m, null, value, expectFailure); 261 } 262 setLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)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 } 277 assertEquals(expectFailure, exceptionThrown); 278 } 279 setLong(MethodHandle m, long value, boolean expectFailure)280 static void setLong(MethodHandle m, long value, boolean expectFailure) throws Throwable { 281 setLong(m, null, value, expectFailure); 282 } 283 getLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure)284 static void getLong(MethodHandle m, ValueHolder v, long value, boolean expectFailure) 285 throws Throwable { 286 boolean exceptionThrown = false; 287 try { 288 final long got = (v == null) ? (long) m.invokeExact() : (long) m.invokeExact(v); 289 assertTrue(got == value); 290 } 291 catch (WrongMethodTypeException e) { 292 exceptionThrown = true; 293 } 294 assertEquals(expectFailure, exceptionThrown); 295 } 296 getLong(MethodHandle m, long value, boolean expectFailure)297 static void getLong(MethodHandle m, long value, boolean expectFailure) throws Throwable { 298 getLong(m, null, value, expectFailure); 299 } 300 setFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)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 } 315 assertEquals(expectFailure, exceptionThrown); 316 } 317 setFloat(MethodHandle m, float value, boolean expectFailure)318 static void setFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable { 319 setFloat(m, null, value, expectFailure); 320 } 321 getFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure)322 static void getFloat(MethodHandle m, ValueHolder v, float value, boolean expectFailure) 323 throws Throwable { 324 boolean exceptionThrown = false; 325 try { 326 final float got = (v == null) ? (float) m.invokeExact() : (float) m.invokeExact(v); 327 assertTrue(got == value); 328 } 329 catch (WrongMethodTypeException e) { 330 exceptionThrown = true; 331 } 332 assertEquals(expectFailure, exceptionThrown); 333 } 334 getFloat(MethodHandle m, float value, boolean expectFailure)335 static void getFloat(MethodHandle m, float value, boolean expectFailure) throws Throwable { 336 getFloat(m, null, value, expectFailure); 337 } 338 setDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)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 } 353 assertEquals(expectFailure, exceptionThrown); 354 } 355 setDouble(MethodHandle m, double value, boolean expectFailure)356 static void setDouble(MethodHandle m, double value, boolean expectFailure) 357 throws Throwable { 358 setDouble(m, null, value, expectFailure); 359 } 360 getDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure)361 static void getDouble(MethodHandle m, ValueHolder v, double value, boolean expectFailure) 362 throws Throwable { 363 boolean exceptionThrown = false; 364 try { 365 final double got = (v == null) ? (double) m.invokeExact() : (double) m.invokeExact(v); 366 assertTrue(got == value); 367 } 368 catch (WrongMethodTypeException e) { 369 exceptionThrown = true; 370 } 371 assertEquals(expectFailure, exceptionThrown); 372 } 373 getDouble(MethodHandle m, double value, boolean expectFailure)374 static void getDouble(MethodHandle m, double value, boolean expectFailure) 375 throws Throwable { 376 getDouble(m, null, value, expectFailure); 377 } 378 setString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)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 } 393 assertEquals(expectFailure, exceptionThrown); 394 } 395 setString(MethodHandle m, String value, boolean expectFailure)396 static void setString(MethodHandle m, String value, boolean expectFailure) 397 throws Throwable { 398 setString(m, null, value, expectFailure); 399 } 400 getString(MethodHandle m, ValueHolder v, String value, boolean expectFailure)401 static void getString(MethodHandle m, ValueHolder v, String value, boolean expectFailure) 402 throws Throwable { 403 boolean exceptionThrown = false; 404 try { 405 final String got = (v == null) ? (String) m.invokeExact() : (String) m.invokeExact(v); 406 assertTrue(got.equals(value)); 407 } 408 catch (WrongMethodTypeException e) { 409 exceptionThrown = true; 410 } 411 assertEquals(expectFailure, exceptionThrown); 412 } 413 getString(MethodHandle m, String value, boolean expectFailure)414 static void getString(MethodHandle m, String value, boolean expectFailure) 415 throws Throwable { 416 getString(m, null, value, expectFailure); 417 } 418 setBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)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 } 433 assertEquals(expectFailure, exceptionThrown); 434 } 435 setBoolean(MethodHandle m, boolean value, boolean expectFailure)436 static void setBoolean(MethodHandle m, boolean value, boolean expectFailure) 437 throws Throwable { 438 setBoolean(m, null, value, expectFailure); 439 } 440 getBoolean(MethodHandle m, ValueHolder v, boolean value, boolean expectFailure)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 = 446 (v == null) ? (boolean) m.invokeExact() : (boolean) m.invokeExact(v); 447 assertTrue(got == value); 448 } 449 catch (WrongMethodTypeException e) { 450 exceptionThrown = true; 451 } 452 assertEquals(expectFailure, exceptionThrown); 453 } 454 getBoolean(MethodHandle m, boolean value, boolean expectFailure)455 static void getBoolean(MethodHandle m, boolean value, boolean expectFailure) 456 throws Throwable { 457 getBoolean(m, null, value, expectFailure); 458 } 459 resultFor(PrimitiveType actualType, PrimitiveType expectedType, AccessorType actualAccessor, AccessorType expectedAccessor)460 static boolean resultFor(PrimitiveType actualType, PrimitiveType expectedType, 461 AccessorType actualAccessor, 462 AccessorType expectedAccessor) { 463 return (actualType != expectedType) || (actualAccessor != expectedAccessor); 464 } 465 tryAccessor(MethodHandle methodHandle, ValueHolder valueHolder, PrimitiveType primitive, Object value, AccessorType accessor)466 static void tryAccessor(MethodHandle methodHandle, 467 ValueHolder valueHolder, 468 PrimitiveType primitive, 469 Object value, 470 AccessorType accessor) throws Throwable { 471 boolean booleanValue = 472 value instanceof Boolean ? ((Boolean) value).booleanValue() : false; 473 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 482 byte byteValue = value instanceof Byte ? ((Byte) value).byteValue() : (byte) 0; 483 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 492 char charValue = value instanceof Character ? ((Character) value).charValue() : 'z'; 493 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 502 short shortValue = value instanceof Short ? ((Short) value).shortValue() : (short) 0; 503 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 512 int intValue = value instanceof Integer ? ((Integer) value).intValue() : -1; 513 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 522 long longValue = value instanceof Long ? ((Long) value).longValue() : (long) -1; 523 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 532 float floatValue = value instanceof Float ? ((Float) value).floatValue() : -1.0f; 533 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 542 double doubleValue = value instanceof Double ? ((Double) value).doubleValue() : -1.0; 543 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 main()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 582 byte [] bytes = { (byte) 0x73, (byte) 0xfe }; 583 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 612 short [] shorts = { (short) 0x1234, (short) 0x4321 }; 613 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) { 644 Float boxed = Float.valueOf(f); 645 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) { 659 Double boxed = Double.valueOf(d); 660 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 701 System.out.println("Passed MethodHandle.invokeExact() tests for accessors."); 702 } 703 } 704 705 public static class FindAccessorTester extends Tester { main()706 public static void main() throws Throwable { 707 // 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. 711 MethodHandles.Lookup lookup = MethodHandles.lookup(); 712 { 713 MethodHandle mh = lookup.findStaticGetter(ValueHolder.class, "s_fi", int.class); 714 int initialValue = (int) mh.invokeExact(); 715 System.out.println(initialValue); 716 } 717 { 718 MethodHandle mh = lookup.findStaticSetter(ValueHolder.class, "s_i", int.class); 719 mh.invokeExact(0); 720 } 721 try { 722 lookup.findStaticGetter(ValueHolder.class, "s_fi", byte.class); 723 fail(); 724 } catch (NoSuchFieldException expected) {} 725 try { 726 lookup.findGetter(ValueHolder.class, "s_fi", byte.class); 727 fail(); 728 } catch (NoSuchFieldException eexpected) {} 729 try { 730 lookup.findStaticSetter(ValueHolder.class, "s_fi", int.class); 731 fail(); 732 } catch (IllegalAccessException expected) {} 733 734 lookup.findGetter(ValueHolder.class, "m_fi", int.class); 735 try { 736 lookup.findGetter(ValueHolder.class, "m_fi", byte.class); 737 fail(); 738 } catch (NoSuchFieldException expected) {} 739 try { 740 lookup.findStaticGetter(ValueHolder.class, "m_fi", byte.class); 741 fail(); 742 } catch (NoSuchFieldException expected) {} 743 try { 744 lookup.findSetter(ValueHolder.class, "m_fi", int.class); 745 fail(); 746 } catch (IllegalAccessException expected) {} 747 748 System.out.println("Passed MethodHandles.Lookup tests for accessors."); 749 } 750 } 751 752 public static class InvokeTester extends Tester { testStaticGetter()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(); 757 Number t = (Number) h0.invoke(); 758 int u = (int) h0.invoke(); 759 Integer v = (Integer) h0.invoke(); 760 long w = (long) h0.invoke(); 761 try { 762 byte x = (byte) h0.invoke(); 763 fail(); 764 } catch (WrongMethodTypeException expected) {} 765 try { 766 String y = (String) h0.invoke(); 767 fail(); 768 } catch (WrongMethodTypeException expected) {} 769 try { 770 Long z = (Long) h0.invoke(); 771 fail(); 772 } catch (WrongMethodTypeException expected) {} 773 } 774 testMemberGetter()775 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); 780 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); 784 try { 785 byte x = (byte) h0.invoke(valueHolder); 786 fail(); 787 } catch (WrongMethodTypeException expected) {} 788 try { 789 String y = (String) h0.invoke(valueHolder); 790 fail(); 791 } catch (WrongMethodTypeException expected) {} 792 try { 793 Long z = (Long) h0.invoke(valueHolder); 794 fail(); 795 } catch (WrongMethodTypeException expected) {} 796 } 797 getDoubleAsNumber()798 /*package*/ static Number getDoubleAsNumber() { 799 return Double.valueOf(1.4e77); 800 } getFloatAsNumber()801 /*package*/ static Number getFloatAsNumber() { 802 return Float.valueOf(7.77f); 803 } getFloatAsObject()804 /*package*/ static Object getFloatAsObject() { 805 return Float.valueOf(-7.77f); 806 } 807 testMemberSetter()808 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); 812 MethodHandle s0 = lookup.findSetter(ValueHolder.class, "m_s", short.class); 813 h0.invoke(valueHolder, 0.22f); 814 h0.invoke(valueHolder, Float.valueOf(1.11f)); 815 Number floatNumber = getFloatAsNumber(); 816 h0.invoke(valueHolder, floatNumber); 817 assertTrue(valueHolder.m_f == floatNumber.floatValue()); 818 Object objNumber = getFloatAsObject(); 819 h0.invoke(valueHolder, objNumber); 820 assertTrue(valueHolder.m_f == ((Float) objNumber).floatValue()); 821 try { 822 h0.invoke(valueHolder, (Float) null); 823 fail(); 824 } catch (NullPointerException expected) {} 825 826 // Test that type conversion checks work on small field types. 827 short temp = (short) s0.invoke(valueHolder, new Byte((byte) 45)); 828 assertTrue(temp == 0); 829 assertTrue(valueHolder.m_s == 45); 830 831 h0.invoke(valueHolder, (byte) 1); 832 h0.invoke(valueHolder, (short) 2); 833 h0.invoke(valueHolder, 3); 834 h0.invoke(valueHolder, 4l); 835 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 840 try { 841 h0.invoke(valueHolder, 0.33); 842 fail(); 843 } catch (WrongMethodTypeException expected) {} 844 try { 845 Number doubleNumber = getDoubleAsNumber(); 846 h0.invoke(valueHolder, doubleNumber); 847 fail(); 848 } catch (ClassCastException expected) {} 849 try { 850 Number doubleNumber = null; 851 h0.invoke(valueHolder, doubleNumber); 852 fail(); 853 } catch (NullPointerException expected) {} 854 { 855 // Mismatched return type - float != void 856 float tmp = (float) h0.invoke(valueHolder, 0.45f); 857 assertTrue(tmp == 0.0); 858 } 859 try { 860 h0.invoke(valueHolder, "bam"); 861 fail(); 862 } catch (WrongMethodTypeException expected) {} 863 try { 864 String s = null; 865 h0.invoke(valueHolder, s); 866 fail(); 867 } catch (WrongMethodTypeException expected) {} 868 } 869 testStaticSetter()870 private static void testStaticSetter() throws Throwable { 871 MethodHandles.Lookup lookup = MethodHandles.lookup(); 872 MethodHandle s0 = lookup.findStaticSetter(ValueHolder.class, "s_s", short.class); 873 MethodHandle h0 = lookup.findStaticSetter(ValueHolder.class, "s_f", float.class); 874 h0.invoke(0.22f); 875 h0.invoke(Float.valueOf(1.11f)); 876 Number floatNumber = Float.valueOf(0.88f); 877 h0.invoke(floatNumber); 878 assertTrue(ValueHolder.s_f == floatNumber.floatValue()); 879 880 try { 881 h0.invoke((Float) null); 882 fail(); 883 } catch (NullPointerException expected) {} 884 885 // Test that type conversion checks work on small field types. 886 short temp = (short) s0.invoke(new Byte((byte) 45)); 887 assertTrue(temp == 0); 888 assertTrue(ValueHolder.s_s == 45); 889 890 h0.invoke((byte) 1); 891 h0.invoke((short) 2); 892 h0.invoke(3); 893 h0.invoke(4l); 894 895 assertTrue(null == (Object) h0.invoke(33)); 896 assertTrue(0.0f == (float) h0.invoke(33)); 897 assertTrue(0l == (long) h0.invoke(33)); 898 899 try { 900 h0.invoke(0.33); 901 fail(); 902 } catch (WrongMethodTypeException expected) {} 903 try { 904 h0.invoke(Double.valueOf(0.33)); 905 fail(); 906 } catch (WrongMethodTypeException expected) {} 907 try { 908 Number doubleNumber = getDoubleAsNumber(); 909 h0.invoke(doubleNumber); 910 fail(); 911 } catch (ClassCastException expected) {} 912 try { 913 Number doubleNumber = Double.valueOf(1.01); 914 doubleNumber = (doubleNumber.doubleValue() != 0.1) ? null : doubleNumber; 915 h0.invoke(doubleNumber); 916 fail(); 917 } catch (NullPointerException expected) {} 918 try { 919 // Mismatched return type - float != void 920 float tmp = (float) h0.invoke(0.45f); 921 assertTrue(tmp == 0.0); 922 } catch (Exception e) { fail(); } 923 try { 924 h0.invoke("bam"); 925 fail(); 926 } catch (WrongMethodTypeException expected) {} 927 try { 928 String s = null; 929 h0.invoke(s); 930 fail(); 931 } catch (WrongMethodTypeException expected) {} 932 } 933 main()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."); 940 } 941 } 942 943 public static class UnreflectTester extends Tester { main()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'); 950 assertEquals('z', (char) MethodHandles.lookup().unreflectGetter(f).invokeExact(v)); 951 MethodHandles.lookup().unreflectSetter(f).invokeExact(v, 'A'); 952 assertEquals('A', (char) MethodHandles.lookup().unreflectGetter(f).invokeExact(v)); 953 } 954 { 955 // public static final field test 956 Field f = ValueHolder.class.getDeclaredField("s_fi"); 957 try { 958 MethodHandles.lookup().unreflectSetter(f); 959 fail(); 960 } catch (IllegalAccessException expected) {} 961 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); 966 assertEquals(newValue, (int) MethodHandles.lookup().unreflectGetter(f).invokeExact() 967 ); 968 MethodHandles.lookup().unreflectSetter(f).invokeExact(savedValue); 969 assertEquals(savedValue, (int) MethodHandles.lookup().unreflectGetter(f).invokeExact() 970 ); 971 f.setAccessible(false); 972 try { 973 MethodHandles.lookup().unreflectSetter(f); 974 fail(); 975 } catch (IllegalAccessException expected) {} 976 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); 983 fail(); 984 } catch (IllegalAccessException expected) {} 985 try { 986 MethodHandle mh = MethodHandles.lookup().unreflectGetter(f); 987 fail(); 988 } catch (IllegalAccessException expected) {} 989 f.setAccessible(true); 990 MethodHandles.lookup().unreflectSetter(f).invokeExact(v, true); 991 assertEquals(true, (boolean) MethodHandles.lookup().unreflectGetter(f).invokeExact(v) 992 ); 993 MethodHandles.lookup().unreflectSetter(f).invokeExact(v, false); 994 assertEquals(false, (boolean) MethodHandles.lookup().unreflectGetter(f).invokeExact(v) 995 ); 996 f.setAccessible(false); 997 try { 998 MethodHandle mh = MethodHandles.lookup().unreflectGetter(f); 999 fail(); 1000 } catch (IllegalAccessException expected) {} 1001 try { 1002 MethodHandle mh = MethodHandles.lookup().unreflectSetter(f); 1003 fail(); 1004 } catch (IllegalAccessException expected) {} 1005 } 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); 1011 fail(); 1012 } catch (IllegalAccessException expected) {} 1013 try { 1014 MethodHandles.lookup().unreflectGetter(f); 1015 fail(); 1016 } catch (IllegalAccessException expected) {} 1017 f.setAccessible(true); 1018 // Setter is okay despite being final because field isAccessible(). 1019 MethodHandles.lookup().unreflectSetter(f).invokeExact(false); 1020 assertEquals(false, (boolean) MethodHandles.lookup().unreflectGetter(f).invokeExact() 1021 ); 1022 MethodHandles.lookup().unreflectSetter(f).invokeExact(true); 1023 assertEquals(true, (boolean) MethodHandles.lookup().unreflectGetter(f).invokeExact() 1024 ); 1025 f.setAccessible(false); 1026 try { 1027 MethodHandles.lookup().unreflectSetter(f); 1028 fail(); 1029 } catch (IllegalAccessException expected) {} 1030 try { 1031 MethodHandles.lookup().unreflectGetter(f); 1032 fail(); 1033 } catch (IllegalAccessException expected) {} 1034 } 1035 System.out.println("Passed MethodHandles.unreflect(Field) tests."); 1036 } 1037 } 1038 main(String[] args)1039 public static void main(String[] args) throws Throwable { 1040 // FindAccessor test should be the first test class in this 1041 // file to ensure class initialization test is run. 1042 FindAccessorTester.main(); 1043 InvokeExactTester.main(); 1044 InvokeTester.main(); 1045 UnreflectTester.main(); 1046 } 1047 } 1048