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