public static void main(String[] args) throws Throwable { l = MethodHandles.lookup(); h = l.findVirtual(LambdaReceiver_A.class, "f", mt(int.class)); MethodType X = mt(int.class, LambdaReceiverBridge.class); MethodType A = mt(int.class, LambdaReceiver_A.class); MethodType mti = mt(IA.class); CallSite cs = LambdaMetafactory.altMetafactory(l, "m", mti,X,h,X, LambdaMetafactory.FLAG_BRIDGES, 1, A); IA p = (IA)cs.dynamicInvoker().invoke(); LambdaReceiver_A lra = new LambdaReceiver_A(); try { p.m(lra); } catch (ClassCastException cce) { return; } throw new AssertionError("CCE expected"); }
public static void main(String[] args) throws Throwable { l = MethodHandles.lookup(); h = l.findVirtual(LambdaReceiver_A.class, "f", mt(int.class)); MethodType X = mt(int.class, LambdaReceiver.class); MethodType A = mt(int.class, LambdaReceiver_A.class); MethodType mti = mt(IA.class); CallSite cs = LambdaMetafactory.metafactory(l, "m", mti,A,h,X); IA p = (IA)cs.dynamicInvoker().invoke(); LambdaReceiver_A lra = new LambdaReceiver_A(); try { p.m(lra); } catch (ClassCastException cce) { return; } throw new AssertionError("CCE expected"); }
private Function getter(Method method) throws CodecGenerationException { try { MethodHandles.Lookup caller = MethodHandles.lookup(); MethodHandle handle = caller.unreflect(method); return (Function) LambdaMetafactory .metafactory( caller, "apply", MethodType.methodType(Function.class), MethodType.methodType(Object.class, Object.class), handle, handle.type()) .getTarget() .invoke(); } catch (Throwable e) { throw new CodecGenerationException("Could not generate the function to access the getter " + method.getName(), e); } }
private BiConsumer setter(Method method) throws CodecGenerationException { try { MethodHandles.Lookup caller = MethodHandles.lookup(); MethodHandle handle = caller.unreflect(method); return (BiConsumer) LambdaMetafactory .metafactory( caller, "accept", MethodType.methodType(BiConsumer.class), MethodType.methodType(Void.TYPE, Object.class, Object.class), handle, handle.type()) .getTarget() .invoke(); } catch (Throwable e) { throw new CodecGenerationException("Could not generate the function to access the setter " + method.getName(), e); } }
@Test public void accessInstanceMethodWithFunction() throws Throwable { SimpleBean simpleBeanInstance = new SimpleBean(); MethodHandles.Lookup caller = MethodHandles.lookup(); MethodType getter = MethodType.methodType(Object.class); MethodHandle target = caller.findVirtual(SimpleBean.class, "getObj", getter); MethodType func = target.type(); System.out.println(func); System.out.println(func.generic()); CallSite site = LambdaMetafactory.metafactory(caller, "apply", MethodType.methodType(Function.class), func.generic(), target, func); MethodHandle factory = site.getTarget(); Function r = (Function) factory.invoke(); assertEquals("myCustomObject", r.apply(simpleBeanInstance)); }
@Test public void accessObjectInstanceMethod() throws Throwable { SimpleBean simpleBeanInstance = new SimpleBean(); MethodHandles.Lookup caller = MethodHandles.lookup(); Method reflected = SimpleBean.class.getDeclaredMethod("getObj"); MethodHandle methodHandle = caller.unreflect(reflected); CallSite site = LambdaMetafactory.metafactory(caller, "get", MethodType.methodType(Supplier.class, SimpleBean.class), MethodType.methodType(Object.class), methodHandle, MethodType.methodType(Object.class)); MethodHandle factory = site.getTarget(); factory = factory.bindTo(simpleBeanInstance); Supplier r = (Supplier) factory.invoke(); assertEquals(simpleBeanInstance.getObj(), r.get()); }
@Override void write(MethodWriter writer, Globals globals) { if (ref != null) { writer.writeDebugInfo(location); // convert MethodTypes to asm Type for the constant pool. String invokedType = ref.invokedType.toMethodDescriptorString(); Type samMethodType = Type.getMethodType(ref.samMethodType.toMethodDescriptorString()); Type interfaceType = Type.getMethodType(ref.interfaceMethodType.toMethodDescriptorString()); if (ref.needsBridges()) { writer.invokeDynamic(ref.invokedName, invokedType, LAMBDA_BOOTSTRAP_HANDLE, samMethodType, ref.implMethodASM, samMethodType, LambdaMetafactory.FLAG_BRIDGES, 1, interfaceType); } else { writer.invokeDynamic(ref.invokedName, invokedType, LAMBDA_BOOTSTRAP_HANDLE, samMethodType, ref.implMethodASM, samMethodType, 0); } } else { // TODO: don't do this: its just to cutover :) writer.push((String)null); } }
private static void amf(List<String> errs, MethodHandle h, MethodType mts, MethodType mtf, MethodType mtb, boolean shouldWork) { MethodType mti = mt(I.class); try { LambdaMetafactory.altMetafactory(l, "m", mti, mts,h,mtf, LambdaMetafactory.FLAG_BRIDGES, 1, mtb); } catch(LambdaConversionException e) { if (shouldWork) errs.add("Error: Should work h=" + h + " s=" + mts + " -- f=" + mtf + " / b=" + mtb + " got: " + e); return; } if (!shouldWork) errs.add("Error: Should fail h=" + h + " s=" + mts + " -- f=" + mtf + " / b=" + mtb); }
private static boolean mf(MethodHandles.Lookup l) { try { LambdaMetafactory.metafactory(l, "close", mt(Closeable.class),mt(void.class),h,mt(void.class)); } catch(LambdaConversionException e) { return true; } return false; }
private static boolean mf(Class<?> k) { try { LambdaMetafactory.metafactory(l, "m", mt(I.class),mt(k),h,mt(void.class)); } catch(LambdaConversionException e) { return true; } return false; }
private static boolean mf(MethodType mti, MethodType mtf) { try { LambdaMetafactory.metafactory(l, "m", mti,mtf,h,mtf); } catch(LambdaConversionException e) { return true; } return false; }
public void testDirectStdNonser() throws Throwable { MethodHandle fooMH = MethodHandles.lookup().findStatic(SerializedLambdaTest.class, "foo", predicateMT); // Standard metafactory, non-serializable target: not serializable CallSite cs = LambdaMetafactory.metafactory(MethodHandles.lookup(), "test", MethodType.methodType(Predicate.class), predicateMT, fooMH, stringPredicateMT); Predicate<String> p = (Predicate<String>) cs.getTarget().invokeExact(); assertNotSerial(p, fooAsserter); }
public void testDirectStdSer() throws Throwable { MethodHandle fooMH = MethodHandles.lookup().findStatic(SerializedLambdaTest.class, "foo", predicateMT); // Standard metafactory, serializable target: not serializable CallSite cs = LambdaMetafactory.metafactory(MethodHandles.lookup(), "test", MethodType.methodType(SerPredicate.class), predicateMT, fooMH, stringPredicateMT); assertNotSerial((SerPredicate<String>) cs.getTarget().invokeExact(), fooAsserter); }
public void testAltStdNonser() throws Throwable { MethodHandle fooMH = MethodHandles.lookup().findStatic(SerializedLambdaTest.class, "foo", predicateMT); // Alt metafactory, non-serializable target: not serializable CallSite cs = LambdaMetafactory.altMetafactory(MethodHandles.lookup(), "test", MethodType.methodType(Predicate.class), predicateMT, fooMH, stringPredicateMT, 0); assertNotSerial((Predicate<String>) cs.getTarget().invokeExact(), fooAsserter); }
public void testAltStdSer() throws Throwable { MethodHandle fooMH = MethodHandles.lookup().findStatic(SerializedLambdaTest.class, "foo", predicateMT); // Alt metafactory, serializable target, no FLAG_SERIALIZABLE: not serializable CallSite cs = LambdaMetafactory.altMetafactory(MethodHandles.lookup(), "test", MethodType.methodType(SerPredicate.class), predicateMT, fooMH, stringPredicateMT, 0); assertNotSerial((SerPredicate<String>) cs.getTarget().invokeExact(), fooAsserter); // Alt metafactory, serializable marker, no FLAG_SERIALIZABLE: not serializable cs = LambdaMetafactory.altMetafactory(MethodHandles.lookup(), "test", MethodType.methodType(Predicate.class), predicateMT, fooMH, stringPredicateMT, LambdaMetafactory.FLAG_MARKERS, 1, Serializable.class); assertNotSerial((Predicate<String>) cs.getTarget().invokeExact(), fooAsserter); }