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