MethodHandlesTest.java revision 5453
3907N/A * @compile -source 7 -target 7 MethodHandlesTest.java
2038N/Apublic class MethodHandlesTest {
2038N/A static boolean CAN_SKIP_WORKING = false;
5452N/A static boolean CAN_TEST_LIGHTLY = Boolean.getBoolean(THIS_CLASS.getName()+".CAN_TEST_LIGHTLY");
2431N/A // AMH.<init>: IllegalArgumentException: bad adapter (conversion=0xfffab300): adapter pushes too many parameters
5452N/A @Test //@Ignore("failure in JVM when expanding the stack using asm stub for _adapter_spread_args")
2431N/A // ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
2431N/A // ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
2431N/A // ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
2431N/A // ValueConversions.varargsArray: UnsupportedOperationException: NYI: cannot form a varargs array of length 13
2038N/A public MethodHandlesTest() {
2038N/A public void printCounts() {
2038N/A if (posTests != 0) System.out.println("=== "+testName+": "+posTests+" positive test cases run");
2038N/A if (negTests != 0) System.out.println("=== "+testName+": "+negTests+" negative test cases run");
2431N/A static long nextArgVal;
2038N/A public static interface IntExample {
2431N/A { { false, PUBLIC }, { false, PACKAGE }, { false, PRIVATE }, { false, EXAMPLE } }, //[0]: all false
2431N/A { { false, PUBLIC }, { false, PACKAGE }, { true, PRIVATE }, { true, EXAMPLE } }, //[1]: only PRIVATE
2431N/A { { false, PUBLIC }, { true, PACKAGE }, { true, PRIVATE }, { true, EXAMPLE } }, //[2]: PUBLIC false
2431N/A { { true, PUBLIC }, { true, PACKAGE }, { true, PRIVATE }, { true, EXAMPLE } }, //[3]: all true
2038N/A if (CAN_SKIP_WORKING) return;
2038N/A void testFindStatic(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2038N/A void testFindStatic(Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2038N/A void testFindStatic(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2038N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
4245N/A static final boolean DEBUG_METHOD_HANDLE_NAMES = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
4245N/A if (!DEBUG_METHOD_HANDLE_NAMES) {
3240N/A assertEquals(s, x);
2038N/A if (CAN_SKIP_WORKING) return;
2038N/A void testFindVirtual(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2038N/A void testFindVirtual(Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2038N/A void testFindVirtual(Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2038N/A void testFindVirtual(boolean positive, Lookup lookup, Class<?> rcvc, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2431N/A System.out.println("findVirtual "+lookup+": "+defc.getName()+"."+name+"/"+type+" => "+target
2038N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
2038N/A if (CAN_SKIP_WORKING) return;
2431N/A testFindSpecial(false, lookup, SubExample.class, Example.class, void.class, "<init>", int.class);
2431N/A System.out.println("findSpecial from "+specialCaller.getName()+" to "+defc.getName()+"."+name+"/"+type+" => "+target
2038N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
5452N/A if (CAN_SKIP_WORKING) return;
5452N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
2038N/A if (CAN_SKIP_WORKING) return;
2038N/A void testBind(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2038N/A void testBind(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2038N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
2038N/A if (CAN_SKIP_WORKING) return;
2038N/A void testUnreflect(Class<?> defc, boolean isStatic, Class<?> ret, String name, Class<?>... params) throws Throwable {
2431N/A testUnreflectMaybeSpecial(null, (Boolean)ac[0], (Lookup)ac[1], defc, (isStatic ? null : defc), ret, name, params);
2431N/A void testUnreflect(Class<?> defc, Class<?> rcvc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2431N/A testUnreflectMaybeSpecial(null, (Boolean)ac[0], (Lookup)ac[1], defc, rcvc, ret, name, params);
2431N/A Class<?> defc, Class<?> rcvc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2431N/A System.out.println("unreflect"+(isSpecial?"Special":"")+" "+defc.getName()+"."+name+"/"+type
2038N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
2431N/A void testUnreflectSpecial(Class<?> defc, Class<?> rcvc, Class<?> ret, String name, Class<?>... params) throws Throwable {
2431N/A testUnreflectMaybeSpecial(specialCaller, (Boolean)ac[0], (Lookup)ac[1], defc, rcvc, ret, name, params);
2431N/A if (CAN_SKIP_WORKING) return;
2431N/A testUnreflectSpecial(Example.class, Example.class, Object.class, "v2", int.class, int.class);
2431N/A testUnreflectSpecial(Example.class, SubExample.class, Object.class, "v2", int.class, int.class);
2431N/A testUnreflectMaybeSpecial(Example.class, false, PRIVATE, Example.class, Example.class, void.class, "s0");
3530N/A cases.add(new Object[]{ new Object[]{ false, HasFields.class, "bogus_fD", double.class }, Error.class });
3530N/A cases.add(new Object[]{ new Object[]{ true, HasFields.class, "bogus_sL", Object.class }, Error.class });
3530N/A static final int TEST_UNREFLECT = 1, TEST_FIND_FIELD = 2, TEST_FIND_STATIC = 3, TEST_SETTER = 0x10;
5452N/A System.out.println("testAccessor"+Arrays.asList(positive, lookup, fieldRef, value, testMode0));
3530N/A case TEST_SETTER|
3530N/A case TEST_SETTER|
3530N/A case TEST_SETTER|
3530N/A System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
3530N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, mh != null);
4250N/A .changeReturnType(void.class)
2431N/A testArrayElementGetterSetter(false);
2040N/A public void testArrayElementGetterSetter(Object array, boolean testSetter) throws Throwable {
5452N/A if (verbosity > 2) System.out.println("array type = "+array.getClass().getComponentType().getName()+"["+Array.getLength(array)+"]");
2040N/A if (testSetter) {
2040N/A if (!testSetter) {
2038N/A if (CAN_SKIP_WORKING) return;
2038N/A void testConvert(MethodHandle id, Class<?> rtype, String name, Class<?>... params) throws Throwable {
2038N/A assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
2040N/A if (CAN_SKIP_WORKING) return;
5452N/A if (CAN_TEST_LIGHTLY) return;
2040N/A public void testPermuteArguments(int max, Class<?> type1, int t2c, Class<?> type2, int dilution) throws Throwable {
5452N/A if (CAN_TEST_LIGHTLY) continue;
5452N/A if (CAN_TEST_LIGHTLY && outargs >= 3 && (reorder[0] == reorder[1] || reorder[1] == reorder[2])) continue;
2040N/A void testPermuteArguments(Object[] args, Class<?>[] types, int[] reorder) throws Throwable {
4183N/A System.out.println("*** failed permuteArguments "+Arrays.toString(reorder)+" types="+Arrays.asList(types));
2040N/A if (CAN_SKIP_WORKING) return;
4183N/A Object args2 = ValueConversions.changeArrayType(arrayType, Arrays.copyOfRange(args, pos, args.length));
4183N/A args1[pos] = ValueConversions.changeArrayType(arrayType, Arrays.copyOfRange(args, pos, args.length));
2040N/A if (CAN_SKIP_WORKING) return;
2038N/A if (CAN_SKIP_WORKING) return;
2038N/A // System.out.println("*** fail at n/p/i = "+nargs+"/"+pos+"/"+ins+": "+resList+" => "+res2List);
3529N/A if (CAN_SKIP_WORKING) return;
3529N/A CharSequence.class,
3529N/A System.out.println("*** fail at n/rt = "+nargs+"/"+rtype.getSimpleName()+": "+Arrays.asList(argsToPass)+" => "+result+" != "+expected);
2040N/A if (CAN_SKIP_WORKING) return;
3529N/A System.out.println("*** fail at n/p = "+nargs+"/"+pos+": "+Arrays.asList(argsToPass)+" => "+result+" != "+expected);
2040N/A if (CAN_SKIP_WORKING) return;
3529N/A System.out.println("*** fail at n/p/f = "+nargs+"/"+pos+"/"+fold+": "+argsToPass+" => "+result+" != "+expected);
2040N/A if (CAN_SKIP_WORKING) return;
2040N/A // System.out.println("*** fail at n/p/d = "+nargs+"/"+pos+"/"+drop+": "+argsToDrop+" => "+res2List);
2040N/A if (CAN_SKIP_WORKING) return;
2431N/A result = inv.invokeExact(target, args[0], args[1], args[2], Arrays.copyOfRange(args, 3, nargs));
2038N/A assertEquals(x, y);
2038N/A assertEquals(x, y);
2040N/A if (CAN_SKIP_WORKING) return;
2040N/A MethodHandle test = PRIVATE.findVirtual(Object.class, "equals", MethodType.methodType(boolean.class, Object.class));
5452N/A MethodHandle target = PRIVATE.findStatic(MethodHandlesTest.class, "targetIfEquals", MethodType.genericMethodType(nargs1));
5452N/A MethodHandle fallback = PRIVATE.findStatic(MethodHandlesTest.class, "fallbackIfNotEquals", MethodType.genericMethodType(nargs1));
5452N/A test1 = MethodHandles.insertArguments(test, testArgs, Arrays.copyOfRange(argList1, testArgs, pc));
2040N/A if (CAN_SKIP_WORKING) return;
5452N/A static final int THROW_NOTHING = 0, THROW_CAUGHT = 1, THROW_UNCAUGHT = 2, THROW_THROUGH_ADAPTER = 3, THROW_MODE_LIMIT = 4;
5452N/A void testCatchException(Class<?> returnType, Throwable thrown, int throwMode, int nargs) throws Throwable {
5452N/A private int fakeIdentityCount;
5452N/A void testCatchException(Class<?> returnType, Throwable thrown, int throwMode, int nargs, int catchDrops) throws Throwable {
5452N/A System.out.println("catchException rt="+returnType+" throw="+throwMode+" nargs="+nargs+" drops="+catchDrops);
5452N/A if (throwMode > THROW_CAUGHT) thrown = new UnsupportedOperationException("do not catch this");
5452N/A MethodHandle catcher = varargsList(catchArgc).asType(MethodType.genericMethodType(catchArgc));
5452N/A assertCalled("throwOrReturn/"+(throwMode == THROW_NOTHING ? "normal" : "throw"), arg0, arg1);
2040N/A if (CAN_SKIP_WORKING) return;
5452N/A for (Class<?> ctype : new Class<?>[]{ Object.class, String.class, CharSequence.class, Number.class, Iterable.class}) {
5452N/A public void testInterfaceCast(Class<?> ctype, boolean doret, boolean docast) throws Throwable {
5452N/A System.out.println("*** testInterfaceCast: "+mh+" was "+mt+" => "+res+(docast ? " (explicitCastArguments)" : ""));
2040N/A if (CAN_SKIP_WORKING) return;
3011N/A MethodHandle identity = Surprise.REF_IDENTITY, surprise0 = boo.asMethodHandle(), surprise = surprise0;
2040N/A assertEquals(x, y);
2040N/A assertEquals(x, z);
2040N/A assertEquals(x, y);
2040N/A assertTrue(false);
2432N/A if (CAN_SKIP_WORKING) return;
3012N/A static void runForRunnable() {
3012N/A if (CAN_SKIP_WORKING) return;
5452N/A MethodHandle append = lookup.bind(appendResults, "add", MethodType.methodType(boolean.class, Object.class));
5452N/A append = append.asType(MethodType.methodType(void.class, List.class)); // specialize the type
5452N/A MethodHandle asList = lookup.findStatic(Arrays.class, "asList", MethodType.methodType(List.class, Object[].class));
5452N/A MethodHandle mh = MethodHandles.filterReturnValue(asList, append).asVarargsCollector(Object[].class);
3012N/A new MyCheckedException()
3012N/A assertTrue(false);
3012N/A CharSequence.class,
5452N/A PrivateRunnable.class,
5453N/A if (CAN_SKIP_WORKING) return;
5453N/A MethodHandle run = lookup.findStatic(lookup.lookupClass(), "runForRunnable", MethodType.methodType(void.class));
2038N/Aclass ValueConversions {
4183N/A MethodType vaType = MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType));
4606N/A AS_LIST = IMPL_LOOKUP.findStatic(Arrays.class, "asList", MethodType.methodType(List.class, Object[].class));
2038N/Aclass PackageSibling {