MethodHandlesTest.java revision 3793
0N/A * @compile -source 7 -target 7 -XDallowTransitionalJSR292=no MethodHandlesTest.java
0N/A * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles test.java.lang.invoke.MethodHandlesTest
0N/Apublic class MethodHandlesTest {
0N/A static boolean CAN_SKIP_WORKING = false;
0N/A static boolean DO_MORE_CALLS = true;
0N/A // AMH.<init>: IllegalArgumentException: bad adapter (conversion=0xfffab300): adapter pushes too many parameters
0N/A @Test @Ignore("failure in JVM when expanding the stack using asm stub for _adapter_spread_args")
0N/A // ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
0N/A // ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
0N/A // ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
0N/A // ValueConversions.varargsArray: UnsupportedOperationException: NYI: cannot form a varargs array of length 13
0N/A public MethodHandlesTest() {
0N/A public void checkImplementedPlatform() {
0N/A boolean platformOK = false;
0N/A platformOK = true;
0N/A System.err.println("Skipping tests for unsupported platform: "+Arrays.asList(vers, name, arch));
0N/A public void printCounts() {
0N/A if (posTests != 0) System.out.println("=== "+testName+": "+posTests+" positive test cases run");
0N/A if (negTests != 0) System.out.println("=== "+testName+": "+negTests+" negative test cases run");
0N/A static long nextArgVal;
0N/A public static interface IntExample {
0N/A { { false, PUBLIC }, { false, PACKAGE }, { false, PRIVATE }, { false, EXAMPLE } }, //[0]: all false
0N/A { { false, PUBLIC }, { false, PACKAGE }, { true, PRIVATE }, { true, EXAMPLE } }, //[1]: only PRIVATE
0N/A { { false, PUBLIC }, { true, PACKAGE }, { true, PRIVATE }, { true, EXAMPLE } }, //[2]: PUBLIC false
0N/A if (CAN_SKIP_WORKING) return;
0N/A void testFindStatic(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A void testFindStatic(Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A void testFindStatic(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
0N/A assertEquals(s, x);
0N/A if (CAN_SKIP_WORKING) return;
0N/A void testFindVirtual(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A void testFindVirtual(Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A void testFindVirtual(Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A void testFindVirtual(boolean positive, Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
0N/A if (CAN_SKIP_WORKING) return;
0N/A testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "<init>", int.class);
0N/A System.out.println("findSpecial from "+specialCaller.getName()+" to "+defc.getName()+"."+name+"/"+type+" => "+target
0N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
0N/A if (CAN_SKIP_WORKING) return;
0N/A void testBind(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
0N/A if (CAN_SKIP_WORKING) return;
0N/A void testUnreflect(Class<?> defc, boolean isStatic, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A testUnreflectMaybeSpecial(null, (Boolean)ac[0], (Lookup)ac[1], defc, (isStatic ? null : defc), ret, name, params);
0N/A void testUnreflect(Class<?> defc, Class<?> rcvc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A Class<?> defc, Class<?> rcvc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
0N/A void testUnreflectSpecial(Class<?> defc, Class<?> rcvc, Class<?> ret, String name, Class<?>... params) throws Throwable {
0N/A testUnreflectMaybeSpecial(specialCaller, (Boolean)ac[0], (Lookup)ac[1], defc, rcvc, ret, name, params);
0N/A if (CAN_SKIP_WORKING) return;
0N/A testUnreflectSpecial(Example.class, SubExample.class, Object.class, "v2", int.class, int.class);
0N/A testUnreflectMaybeSpecial(Example.class, false, PRIVATE, Example.class, Example.class, void.class, "s0");
0N/A cases.add(new Object[]{ new Object[]{ false, HasFields.class, "bogus_fD", double.class }, Error.class });
0N/A cases.add(new Object[]{ new Object[]{ true, HasFields.class, "bogus_sL", Object.class }, Error.class });
0N/A static final int TEST_UNREFLECT = 1, TEST_FIND_FIELD = 2, TEST_FIND_STATIC = 3, TEST_SETTER = 0x10;
0N/A case TEST_SETTER|
0N/A case TEST_SETTER|
0N/A case TEST_SETTER|
0N/A System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
0N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, mh != null);
0N/A .changeReturnType(void.class)
0N/A testArrayElementGetterSetter(false);
0N/A testArrayElementGetterSetter(true);
0N/A if (verbosity >= 2) System.out.println("array type = "+array.getClass().getComponentType().getName()+"["+Array.getLength(array)+"]");
0N/A if (testSetter)
0N/A if (testSetter) {
0N/A if (!testSetter) {
0N/A if (CAN_SKIP_WORKING) return;
0N/A void testConvert(MethodHandle id, Class<?> rtype, String name, Class<?>... params) throws Throwable {
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
@Test
@Test
if (CAN_SKIP_WORKING) return;
public void testPermuteArguments(int max, Class<?> type1, int t2c, Class<?> type2, int dilution) throws Throwable {
casStep++;
c /= inargs;
if (i + d >= inargs) continue;
return reorder;
countTest();
for (int j : reorder) {
@Test
if (CAN_SKIP_WORKING) return;
countTest();
switch (nargs) {
@Test
if (CAN_SKIP_WORKING) return;
countTest();
@Test
if (CAN_SKIP_WORKING) return;
countTest();
@Test
if (CAN_SKIP_WORKING) return;
List.class,
CharSequence.class,
String.class }) {
countTest();
System.out.println("*** fail at n/rt = "+nargs+"/"+rtype.getSimpleName()+": "+Arrays.asList(argsToPass)+" => "+result+" != "+expected);
@Test
if (CAN_SKIP_WORKING) return;
countTest();
System.out.println("*** fail at n/p = "+nargs+"/"+pos+": "+Arrays.asList(argsToPass)+" => "+result+" != "+expected);
@Test
if (CAN_SKIP_WORKING) return;
countTest();
System.out.println("*** fail at n/p/f = "+nargs+"/"+pos+"/"+fold+": "+argsToPass+" => "+result+" != "+expected);
@Test
if (CAN_SKIP_WORKING) return;
countTest();
// System.out.println("*** fail at n/p/d = "+nargs+"/"+pos+"/"+drop+": "+argsToDrop+" => "+res2List);
@Test
if (CAN_SKIP_WORKING) return;
else if (argType == void.class)
countTest();
countTest();
switch (nargs) {
countTest();
countTest();
assertEquals(x, y);
assertEquals(x, y);
@Test
if (CAN_SKIP_WORKING) return;
countTest();
MethodHandle test = PRIVATE.findVirtual(Object.class, "equals", MethodType.methodType(boolean.class, Object.class));
MethodHandle target = PRIVATE.findStatic(MethodHandlesTest.class, "targetIfEquals", MethodType.genericMethodType(nargs));
MethodHandle fallback = PRIVATE.findStatic(MethodHandlesTest.class, "fallbackIfNotEquals", MethodType.genericMethodType(nargs));
boolean equals;
switch (nargs) {
@Test
if (CAN_SKIP_WORKING) return;
private static <T extends Throwable>
return normal;
void testCatchException(Class<?> returnType, Throwable thrown, boolean throwIt, int nargs) throws Throwable {
countTest();
if (!throwIt) {
@Test
if (CAN_SKIP_WORKING) return;
countTest();
@Test
if (CAN_SKIP_WORKING) return;
static class Surprise {
countTest(false);
MethodHandle identity = Surprise.REF_IDENTITY, surprise0 = boo.asMethodHandle(), surprise = surprise0;
surprise = MethodHandles.convertArguments(surprise, MethodType.methodType(int.class, Object.class));
identity = MethodHandles.convertArguments(identity, MethodType.methodType(int.class, Object.class));
surprise = MethodHandles.convertArguments(surprise, MethodType.methodType(Integer.class, Object.class));
identity = MethodHandles.convertArguments(identity, MethodType.methodType(Integer.class, Object.class));
assertEquals(x, y);
assertEquals(x, z);
assertEquals(x, y);
assertTrue(false);
return null;
@Test
if (CAN_SKIP_WORKING) return;
static void runForRunnable() {
private interface Fooable {
private interface WillThrow {
@Test
if (CAN_SKIP_WORKING) return;
new MyCheckedException()
assertTrue(false);
String.class,
CharSequence.class,
Example.class }) {
assertTrue(false);
class ValueConversions {
class PackageSibling {