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"); }
/** * Generate test with an invokedynamic, a static bootstrap method without extra args and * args to the target method. */ private void generateMethodTest2(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test2", "()V", null, null); MethodType mt = MethodType.methodType( CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmLookupStatic", mt.toMethodDescriptorString(), false); mv.visitLdcInsn(new Boolean(true)); mv.visitLdcInsn(new Byte((byte) 127)); mv.visitLdcInsn(new Character('c')); mv.visitLdcInsn(new Short((short) 1024)); mv.visitLdcInsn(new Integer(123456)); mv.visitLdcInsn(new Float(1.2f)); mv.visitLdcInsn(new Long(123456789)); mv.visitLdcInsn(new Double(3.5123456789)); mv.visitLdcInsn("String"); mv.visitInvokeDynamicInsn("targetMethodTest2", "(ZBCSIFJDLjava/lang/String;)V", bootstrap); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invokespecial. */ private void generateMethodTest4(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test4", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle( Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallSite", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest5", "(Linvokecustom/InvokeCustom;)V", bootstrap, new Handle( Opcodes.H_INVOKESPECIAL, Type.getInternalName(Super.class), "targetMethodTest5", "()V", false)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke interface. The target method is a default method into an interface * that shadows another default method from a super interface. */ private void generateMethodTest5(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test5", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest6", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest6", "(Linvokecustom/I;)V", bootstrap, new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(I.class), "targetMethodTest6", "()V", true)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke interface. The target method is a default method into an interface * that is at the end of a chain of interfaces. */ private void generateMethodTest6(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test6", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest7", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest7", "(Linvokecustom/J;)V", bootstrap, new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class), "targetMethodTest7", "()V", true)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke interface. The target method is a method into an interface * that is shadowed by another definition into a sub interfaces. */ private void generateMethodTest7(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test7", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest8", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest8", "(Linvokecustom/J;)V", bootstrap, new Handle(Opcodes.H_INVOKEINTERFACE, Type.getInternalName(J.class), "targetMethodTest8", "()V", true)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke virtual. The target method is a method into an interface that is * not shadowed by an implementation into a classes implementing the interface. */ private void generateMethodTest8(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test8", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest9", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest9", "(Linvokecustom/InvokeCustom;)V", bootstrap, new Handle(Opcodes.H_INVOKEVIRTUAL, Type.getInternalName(InvokeCustom.class), "targetMethodTest9", "()V", false)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind invoke virtual. The target method is a method into a class implementing * an abstract method and that shadows a default method from an interface. */ private void generateMethodTest9(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test9", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethodTest10", mt.toMethodDescriptorString(), false); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("targetMethodTest10", "(Linvokecustom/InvokeCustom;)V", bootstrap, new Handle(Opcodes.H_INVOKEVIRTUAL, Type.getInternalName(InvokeCustom.class), "targetMethodTest10", "()V", false)); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind get static. The method handle read a static field from a class. */ private void generateMethodTest10(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test10", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethod", mt.toMethodDescriptorString(), false); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitInvokeDynamicInsn("staticField1", "()Ljava/lang/String;", bootstrap, new Handle(Opcodes.H_GETSTATIC, Type.getInternalName(InvokeCustom.class), "staticField1", "Ljava/lang/String;", false)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** * Generate test with an invokedynamic, a static bootstrap method with an extra arg that is a * MethodHandle of kind get instance. The method handle read an instance field from a class. */ private void generateMethodTest12(ClassVisitor cv) { MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "test12", "()V", null, null); MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodHandle.class); Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(InvokeCustom.class), "bsmCreateCallCallingtargetMethod", mt.toMethodDescriptorString(), false); mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(InvokeCustom.class)); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn( Opcodes.INVOKESPECIAL, Type.getInternalName(InvokeCustom.class), "<init>", "()V", false); mv.visitInvokeDynamicInsn("instanceField1", "(Linvokecustom/InvokeCustom;)Ljava/lang/String;", bootstrap, new Handle(Opcodes.H_GETFIELD, Type.getInternalName(InvokeCustom.class), "instanceField1", "Ljava/lang/String;", false)); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(-1, -1); }
/** calls toString() on integers, twice */ public void testOneType() throws Throwable { CallSite site = DefBootstrap.bootstrap(MethodHandles.publicLookup(), "toString", MethodType.methodType(String.class, Object.class), 0, DefBootstrap.METHOD_CALL, ""); MethodHandle handle = site.dynamicInvoker(); assertDepthEquals(site, 0); // invoke with integer, needs lookup assertEquals("5", (String)handle.invokeExact((Object)5)); assertDepthEquals(site, 1); // invoked with integer again: should be cached assertEquals("6", (String)handle.invokeExact((Object)6)); assertDepthEquals(site, 1); }
public void testTwoTypes() throws Throwable { CallSite site = DefBootstrap.bootstrap(MethodHandles.publicLookup(), "toString", MethodType.methodType(String.class, Object.class), 0, DefBootstrap.METHOD_CALL, ""); MethodHandle handle = site.dynamicInvoker(); assertDepthEquals(site, 0); assertEquals("5", (String)handle.invokeExact((Object)5)); assertDepthEquals(site, 1); assertEquals("1.5", (String)handle.invokeExact((Object)1.5f)); assertDepthEquals(site, 2); // both these should be cached assertEquals("6", (String)handle.invokeExact((Object)6)); assertDepthEquals(site, 2); assertEquals("2.5", (String)handle.invokeExact((Object)2.5f)); assertDepthEquals(site, 2); }
public void testTooManyTypes() throws Throwable { // if this changes, test must be rewritten assertEquals(5, DefBootstrap.PIC.MAX_DEPTH); CallSite site = DefBootstrap.bootstrap(MethodHandles.publicLookup(), "toString", MethodType.methodType(String.class, Object.class), 0, DefBootstrap.METHOD_CALL, ""); MethodHandle handle = site.dynamicInvoker(); assertDepthEquals(site, 0); assertEquals("5", (String)handle.invokeExact((Object)5)); assertDepthEquals(site, 1); assertEquals("1.5", (String)handle.invokeExact((Object)1.5f)); assertDepthEquals(site, 2); assertEquals("6", (String)handle.invokeExact((Object)6L)); assertDepthEquals(site, 3); assertEquals("3.2", (String)handle.invokeExact((Object)3.2d)); assertDepthEquals(site, 4); assertEquals("foo", (String)handle.invokeExact((Object)"foo")); assertDepthEquals(site, 5); assertEquals("c", (String)handle.invokeExact((Object)'c')); assertDepthEquals(site, 5); }
private static void relinkComposableInvoker(final CallSite cs, final CompiledFunction inv, final boolean constructor) { final HandleAndAssumptions handleAndAssumptions = inv.getValidOptimisticInvocation(new Supplier<MethodHandle>() { @Override public MethodHandle get() { return inv.getInvokerOrConstructor(constructor); } }); final MethodHandle handle = handleAndAssumptions.handle; final SwitchPoint assumptions = handleAndAssumptions.assumptions; final MethodHandle target; if(assumptions == null) { target = handle; } else { final MethodHandle relink = MethodHandles.insertArguments(RELINK_COMPOSABLE_INVOKER, 0, cs, inv, constructor); target = assumptions.guardWithTest(handle, MethodHandles.foldArguments(cs.dynamicInvoker(), relink)); } cs.setTarget(target.asType(cs.type())); }
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 Handle generateBootstrapMethod(Handle h) { String bootstrapName = "bootstrapMethod"; MethodType bootstrapType = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class); MethodVisitor bmv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, bootstrapName, bootstrapType.toMethodDescriptorString(), null, null); bmv.visitCode(); String constCallSite = "java/lang/invoke/ConstantCallSite"; bmv.visitTypeInsn(NEW, constCallSite); bmv.visitInsn(DUP); bmv.visitLdcInsn(h); bmv.visitMethodInsn(INVOKESPECIAL, constCallSite, "<init>", "(Ljava/lang/invoke/MethodHandle;)V", false); bmv.visitInsn(ARETURN); bmv.visitMaxs(0,0); bmv.visitEnd(); return new Handle(H_INVOKESTATIC, ownerClassName, bootstrapName, bootstrapType.toMethodDescriptorString()); }
@Test(dataProvider = "flags") public void systemLoadLibraryTest(final boolean publicLookup) { final CallSite cs1 = createGetMethodCallSite(publicLookup, "loadLibrary"); final CallSite cs2 = createCallSite(publicLookup, CALL, MethodType.methodType(void.class, Object.class, Object.class, String.class)); try { final Object method = cs1.getTarget().invoke(StaticClass.forClass(System.class)); cs2.getTarget().invoke(method, StaticClass.forClass(System.class), "foo"); throw new RuntimeException("should not reach here in any case!"); } catch (final Throwable th) { if (publicLookup) { Assert.assertTrue(th instanceof IllegalAccessError); } else { Assert.assertTrue(th instanceof AccessControlException); } } }
@Test public void testRelink() { final DynamicLinkerFactory factory = new DynamicLinkerFactory(); final DynamicLinker linker = factory.createLinker(); final MethodType mt = MethodType.methodType(Object.class, Object.class); final boolean[] relinkCalled = { Boolean.FALSE }; final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), GET_PROPERTY.named("class"), mt)) { @Override public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) { relinkCalled[0] = Boolean.TRUE; super.relink(guardedInvocation, relinkAndInvoke); } }); Assert.assertFalse(relinkCalled[0]); try { cs.getTarget().invoke(new Object()); } catch (final Throwable th) {} Assert.assertTrue(relinkCalled[0]); }
@Test public void prelinkTransformerTest() throws Throwable { final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); final boolean[] reachedPrelinkTransformer = { false }; factory.setPrelinkTransformer((final GuardedInvocation inv, final LinkRequest linkRequest, final LinkerServices linkerServices) -> { reachedPrelinkTransformer[0] = true; // just identity transformer! return inv; }); final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class); final DynamicLinker linker = factory.createLinker(); final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), GET_PROPERTY, mt))); Assert.assertFalse(reachedPrelinkTransformer[0]); Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class); Assert.assertTrue(reachedPrelinkTransformer[0]); }
@Test public void internalObjectsFilterTest() throws Throwable { final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); final boolean[] reachedInternalObjectsFilter = { false }; factory.setInternalObjectsFilter((final MethodHandle mh) -> { reachedInternalObjectsFilter[0] = true; return mh; }); final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class); final DynamicLinker linker = factory.createLinker(); final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), GET_PROPERTY, mt))); Assert.assertFalse(reachedInternalObjectsFilter[0]); Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class); Assert.assertTrue(reachedInternalObjectsFilter[0]); }
private static void testAutoLoadedLinkerInvoked(final Object target, final String methodName) { final DynamicLinkerFactory factory = newDynamicLinkerFactory(false); final DynamicLinker linker = factory.createLinker(); // we should still get one error due to untrusted dynamic linker exporter! checkOneAutoLoadingError(factory); final MethodType mt = MethodType.methodType(Object.class, Object.class); final CallSiteDescriptor testDescriptor = new CallSiteDescriptor(MethodHandles.publicLookup(), GET.withNamespace(StandardNamespace.METHOD).named(methodName), mt); final CallSite cs = linker.link(new SimpleRelinkableCallSite(testDescriptor)); TrustedGuardingDynamicLinkerExporter.enable(); try { cs.getTarget().invoke(target); // The linker was loaded and it observed our invocation Assert.assertTrue(TrustedGuardingDynamicLinkerExporter.isLastCallSiteDescriptor(testDescriptor)); } catch (final Throwable th) { throw new RuntimeException(th); } finally { TrustedGuardingDynamicLinkerExporter.disable(); } }
@Test public void nashornExportedLinkerScriptObjectMirrorTest() { final DynamicLinkerFactory factory = newDynamicLinkerFactory(false); final DynamicLinker linker = factory.createLinker(); // check that the nashorn exported linker can be used for ScriptObjectMirror final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); final MethodType mt = MethodType.methodType(Object.class, Object.class); final Operation op = GET_PROPERTY.named("foo"); final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), op, mt))); Object value = null; try { final Object obj = engine.eval("({ foo: 'hello' })"); value = cs.getTarget().invoke(obj); } catch (final Throwable th) { throw new RuntimeException(th); } Assert.assertEquals(value, "hello"); }
@Test(dataProvider = "flags") public void getlengthTest(final boolean publicLookup) throws Throwable { final MethodType mt = MethodType.methodType(int.class, Object.class); final CallSite cs = createCallSite(publicLookup, GET_LENGTH, mt); final int[] arr = {23, 42}; Assert.assertEquals((int) cs.getTarget().invoke((Object) arr), 2); Assert.assertEquals((int) cs.getTarget().invoke(Collections.EMPTY_LIST), 0); final List<String> list = new ArrayList<>(); list.add("hello"); list.add("world"); list.add("dynalink"); Assert.assertEquals((int) cs.getTarget().invoke(list), 3); list.add("nashorn"); Assert.assertEquals((int) cs.getTarget().invoke(list), 4); list.clear(); Assert.assertEquals((int) cs.getTarget().invoke(list), 0); }
@Test(dataProvider = "flags") public void systemLoadLibraryTest(final boolean publicLookup) { final MethodType mt = MethodType.methodType(void.class, Object.class, String.class); final CallSite cs = createCallSite(publicLookup, CALL_METHOD, "loadLibrary", mt); try { cs.getTarget().invoke(StaticClass.forClass(System.class), "foo"); throw new RuntimeException("should not reach here in any case!"); } catch (final Throwable th) { if (publicLookup) { Assert.assertTrue(th instanceof IllegalAccessError); } else { Assert.assertTrue(th instanceof AccessControlException); } } }
@Test public void testRelink() { final DynamicLinkerFactory factory = new DynamicLinkerFactory(); final DynamicLinker linker = factory.createLinker(); final MethodType mt = MethodType.methodType(Object.class, Object.class); final boolean[] relinkCalled = { Boolean.FALSE }; final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), new NamedOperation(StandardOperation.GET_PROPERTY, "class"), mt)) { @Override public void relink(final GuardedInvocation guardedInvocation, final MethodHandle relinkAndInvoke) { relinkCalled[0] = Boolean.TRUE; super.relink(guardedInvocation, relinkAndInvoke); } }); Assert.assertFalse(relinkCalled[0]); try { cs.getTarget().invoke(new Object()); } catch (final Throwable th) {} Assert.assertTrue(relinkCalled[0]); }
@Test public void prelinkTransformerTest() throws Throwable { final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); final boolean[] reachedPrelinkTransformer = { false }; factory.setPrelinkTransformer((GuardedInvocation inv, LinkRequest linkRequest, LinkerServices linkerServices) -> { reachedPrelinkTransformer[0] = true; // just identity transformer! return inv; }); final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class); final DynamicLinker linker = factory.createLinker(); final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), StandardOperation.GET_PROPERTY, mt))); Assert.assertFalse(reachedPrelinkTransformer[0]); Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class); Assert.assertTrue(reachedPrelinkTransformer[0]); }
@Test public void internalObjectsFilterTest() throws Throwable { final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); final boolean[] reachedInternalObjectsFilter = { false }; factory.setInternalObjectsFilter((MethodHandle mh) -> { reachedInternalObjectsFilter[0] = true; return mh; }); final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class); final DynamicLinker linker = factory.createLinker(); final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), StandardOperation.GET_PROPERTY, mt))); Assert.assertFalse(reachedInternalObjectsFilter[0]); Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class); Assert.assertTrue(reachedInternalObjectsFilter[0]); }
@Test public void autoLoadedLinkerTest() { final DynamicLinkerFactory factory = newDynamicLinkerFactory(false); final DynamicLinker linker = factory.createLinker(); // we should still get one error due to untrusted dynamic linker exporter! checkOneAutoLoadingError(factory); final MethodType mt = MethodType.methodType(Object.class, Object.class); // create a callsite with TestLinkerOperation final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), new TestLinkerOperation(), mt))); boolean reachedAutoLinker = false; try { cs.getTarget().invoke(new Object()); } catch (ReachedAutoLoadedDynamicLinkerException e) { // TrustedGuardingDynamicLinkerExporter threw exception on TestLinkerOperation as expected! reachedAutoLinker = true; } catch (Throwable th) { throw new RuntimeException(th); } Assert.assertTrue(reachedAutoLinker); }
@Test public void nashornExportedLinkerScriptObjectMirrorTest() { final DynamicLinkerFactory factory = newDynamicLinkerFactory(false); final DynamicLinker linker = factory.createLinker(); // check that the nashorn exported linker can be used for ScriptObjectMirror final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); final MethodType mt = MethodType.methodType(Object.class, Object.class); final NamedOperation op = new NamedOperation(StandardOperation.GET_PROPERTY, "foo"); final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( MethodHandles.publicLookup(), op, mt))); Object value = null; try { final Object obj = engine.eval("({ foo: 'hello' })"); value = cs.getTarget().invoke(obj); } catch (Throwable th) { throw new RuntimeException(th); } Assert.assertEquals(value, "hello"); }