# HG changeset patch # User Jaroslav Tulach # Date 1407647550 -7200 # Node ID da24a2411ee76492c92b8a8f8c4a58d3e8656542 # Parent bd151459ee4f88a8d0dd68a59d7b5c5d32036595 Moving the test to JDK8 project, making it compilable and parsable by Asm diff -r bd151459ee4f -r da24a2411ee7 rt/emul/compact/src/test/java/org/apidesign/vm4brwsr/dynamic/InvokeDynamic.java --- a/rt/emul/compact/src/test/java/org/apidesign/vm4brwsr/dynamic/InvokeDynamic.java Sun Aug 10 07:02:12 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.vm4brwsr.dynamic; - -import java.lang.invoke.CallSite; -import java.lang.invoke.ConstantCallSite; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; - -public class InvokeDynamic { - - public static String dynamicSay() { - return TEST_dynamic_boot1(new InvokeDynamic()); - } - - private static String TEST_dynamic_boot1(InvokeDynamic instance) { - throw new IllegalStateException("Can't touch this"); - } - - public static CallSite boot1(MethodHandles.Lookup lookup, String name, MethodType type) { - try { - return new ConstantCallSite(lookup.findVirtual(InvokeDynamic.class, "instance_sayHello", MethodType.methodType(String.class))); - } catch (NoSuchMethodException | IllegalAccessException e) { - throw new IllegalStateException(e); - } - } - - public String instance_sayHello() { - return "Hello from Dynamic!"; - } -} \ No newline at end of file diff -r bd151459ee4f -r da24a2411ee7 rt/emul/compact/src/test/java/org/apidesign/vm4brwsr/dynamic/InvokeDynamicTest.java --- a/rt/emul/compact/src/test/java/org/apidesign/vm4brwsr/dynamic/InvokeDynamicTest.java Sun Aug 10 07:02:12 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,175 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.vm4brwsr.dynamic; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.invoke.CallSite; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.lang.reflect.Method; -import java.net.URL; -import java.util.Enumeration; -import org.apidesign.vm4brwsr.Bck2Brwsr; -import org.objectweb.asm.ClassReader; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Handle; -import org.objectweb.asm.MethodVisitor; -import org.objectweb.asm.Opcodes; -import static org.objectweb.asm.Opcodes.ASM4; -import static org.objectweb.asm.Opcodes.INVOKESTATIC; -import static org.testng.Assert.*; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * - * @author Jaroslav Tulach - */ -public class InvokeDynamicTest { - private static Class invokeDynamicClass; - private static byte[] invokeDynamicBytes; - private static TestVM code; - - @Test public void simpleDynamicInJava() throws Exception { - Method m = invokeDynamicClass.getMethod("dynamicSay"); - Object ret = m.invoke(m); - assertEquals(ret, "Hello from Dynamic!"); - } - - @Test public void simpleDynamicInJS() throws Exception { - code.assertExec( - "Invoke dynamic can return a value", InvokeDynamic.class, - "dynamic__Ljava_lang_String_2", - "Hello from Dynamic!" - ); - } - - - @AfterClass - public static void releaseTheCode() { - code = null; - } - - // - // the following code is inspired by - // https://code.google.com/p/indy-maven-plugin/ - // which I don't want to use, as it is not in a public repository - // - @BeforeClass - public static void prepareClass() throws Exception { - InputStream is = InvokeDynamic.class.getResourceAsStream("InvokeDynamic.class"); - assertNotNull(is, "Class found"); - - ClassReader reader = new ClassReader(is); - ClassWriter writer = new ClassWriter(reader, 0); - - reader.accept( - new ClassVisitor(ASM4, writer) { - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions - ) { - MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); - return new InvokeDynamicProcessor(mv); - } - }, - 0); - is.close(); - invokeDynamicBytes = writer.toByteArray(); - ClassLoader l = new ClassLoader() { - @Override - public Class loadClass(String name) throws ClassNotFoundException { - if (name.equals(InvokeDynamic.class.getName())) { - return defineClass(name, invokeDynamicBytes, 0, invokeDynamicBytes.length); - } - return super.loadClass(name); - } - }; - invokeDynamicClass = l.loadClass(InvokeDynamic.class.getName()); - - code = TestVM.compileClass( - null, null, new EmulationResourcesWithException(), - InvokeDynamic.class.getName().replace('.', '/') - ); - } - - - private static class InvokeDynamicProcessor extends MethodVisitor { - InvokeDynamicProcessor(MethodVisitor mv) { - super(ASM4, mv); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc) { - if (opcode == INVOKESTATIC) { - if (name.startsWith("TEST_dynamic_")) { - final String shortName = name.substring(13); - Handle mh = new Handle( - Opcodes.H_INVOKESTATIC, owner, shortName, - MethodType.methodType( - CallSite.class, - MethodHandles.Lookup.class, - String.class, - MethodType.class - ).toMethodDescriptorString() - ); - super.visitInvokeDynamicInsn(shortName, desc, mh); - return; - } - } - super.visitMethodInsn(opcode, owner, name, desc); - } - } - - private static class EmulationResourcesWithException implements Bck2Brwsr.Resources { - @Override - public InputStream get(String name) throws IOException { - if ("org/apidesign/vm4brwsr/InvokeDynamic.class".equals(name)) { - return new ByteArrayInputStream(invokeDynamicBytes); - } - if ("java/net/URI.class".equals(name)) { - // skip - return null; - } - if ("java/net/URLConnection.class".equals(name)) { - // skip - return null; - } - if ("java/lang/System.class".equals(name)) { - // skip - return null; - } - Enumeration en = InvokeDynamicTest.class.getClassLoader().getResources(name); - URL u = null; - while (en.hasMoreElements()) { - u = en.nextElement(); - } - if (u == null) { - throw new IOException("Can't find " + name); - } - if (u.toExternalForm().contains("rt.jar!")) { - throw new IOException("No emulation for " + u); - } - return u.openStream(); - } - } - -} diff -r bd151459ee4f -r da24a2411ee7 rt/emul/compact/src/test/java/org/apidesign/vm4brwsr/dynamic/TestVM.java --- a/rt/emul/compact/src/test/java/org/apidesign/vm4brwsr/dynamic/TestVM.java Sun Aug 10 07:02:12 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,297 +0,0 @@ -/** - * Back 2 Browser Bytecode Translator - * Copyright (C) 2012 Jaroslav Tulach - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. Look for COPYING file in the top folder. - * If not, see http://opensource.org/licenses/GPL-2.0. - */ -package org.apidesign.vm4brwsr.dynamic; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import javax.script.Invocable; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.apidesign.vm4brwsr.Bck2Brwsr; -import org.apidesign.vm4brwsr.ObfuscationLevel; -import static org.testng.Assert.*; - -public final class TestVM { - private final Invocable code; - private final CharSequence codeSeq; - private final Object bck2brwsr; - - - private TestVM(Invocable code, CharSequence codeSeq) throws ScriptException, NoSuchMethodException { - this.code = code; - this.codeSeq = codeSeq; - this.bck2brwsr = ((ScriptEngine)code).eval("bck2brwsr(function(n) { return loader.get(n); })"); - ((ScriptEngine)code).getContext().setAttribute("loader", this, ScriptContext.ENGINE_SCOPE); - } - - public Object execCode( - String msg, Class clazz, String method, - Object expRes, Object... args - ) throws Exception { - Object ret = null; - try { - ret = code.invokeMethod(bck2brwsr, "loadClass", clazz.getName()); - List ma = new ArrayList<>(); - ma.add(method); - ma.addAll(Arrays.asList(args)); - ret = code.invokeMethod(ret, "invoke", ma.toArray()); - } catch (ScriptException ex) { - fail("Execution failed in " + dumpJS(codeSeq) + ": " + ex.getMessage(), ex); - } catch (NoSuchMethodException ex) { - fail("Cannot find method in " + dumpJS(codeSeq), ex); - } - if (ret == null && expRes == null) { - return null; - } - if (expRes != null && expRes.equals(ret)) { - return null; - } - if (expRes instanceof Number) { - // in case of Long it is necessary convert it to number - // since the Long is represented by two numbers in JavaScript - try { - final Object toFP = ((ScriptEngine)code).eval("Number.prototype.toFP"); - if (ret instanceof Long) { - ret = code.invokeMethod(toFP, "call", ret); - } - ret = code.invokeFunction("Number", ret); - } catch (ScriptException ex) { - fail("Conversion to number failed in " + dumpJS(codeSeq) + ": " + ex.getMessage(), ex); - } catch (NoSuchMethodException ex) { - fail("Cannot find global Number(x) function in " + dumpJS(codeSeq) + ": " + ex.getMessage(), ex); - } - } - return ret; - } - - void assertExec( - String msg, Class clazz, String method, Object expRes, Object... args - ) throws Exception { - Object ret = execCode(msg, clazz, method, expRes, args); - if (ret == null) { - return; - } - if (expRes instanceof Integer && ret instanceof Double) { - expRes = ((Integer)expRes).doubleValue(); - } - if (expRes != null && expRes.equals(ret)) { - return; - } - assertEquals(ret, expRes, msg + "was: " + ret + "\n" + dumpJS(codeSeq)); - } - - static TestVM compileClass(String... names) throws ScriptException, IOException { - return compileClass(null, names); - } - - static TestVM compileClass(StringBuilder sb, String... names) throws ScriptException, IOException { - return compileClass(sb, null, names); - } - - static TestVM compileClass(StringBuilder sb, ScriptEngine[] eng, String... names) throws ScriptException, IOException { - return compileClass(sb, eng, new EmulationResources(), names); - } - static TestVM compileClass( - StringBuilder sb, - ScriptEngine[] eng, - Bck2Brwsr.Resources resources, - String... names - ) throws ScriptException, IOException { - if (sb == null) { - sb = new StringBuilder(); - } - Bck2Brwsr.generate(sb, resources, names); - ScriptEngineManager sem = new ScriptEngineManager(); - ScriptEngine js = sem.getEngineByExtension("js"); - if (eng != null) { - eng[0] = js; - } - try { - Object res = js.eval(sb.toString()); - assertTrue(js instanceof Invocable, "It is invocable object: " + res); - return new TestVM((Invocable) js, sb); - } catch (Exception ex) { - if (sb.length() > 2000) { - sb = dumpJS(sb); - } - fail("Could not evaluate:" + ex.getClass() + ":" + ex.getMessage() + "\n" + sb, ex); - return null; - } - } - - static TestVM compileClassAsExtension( - StringBuilder sb, ScriptEngine[] eng, - String name, final String resourceName, final String resourceContent - ) throws ScriptException, IOException { - return compileClassesAsExtension(sb, eng, resourceName, resourceContent, name); - } - static TestVM compileClassesAsExtension( - StringBuilder sb, ScriptEngine[] eng, - final String resourceName, final String resourceContent, String... names - ) throws ScriptException, IOException { - if (sb == null) { - sb = new StringBuilder(); - } - if (eng[0] == null) { - ScriptEngineManager sem = new ScriptEngineManager(); - ScriptEngine js = sem.getEngineByExtension("js"); - eng[0] = js; - Bck2Brwsr.generate(sb, new EmulationResources()); - } - Set exp = new HashSet(); - for (String n : names) { - int last = n.lastIndexOf('/'); - exp.add(n.substring(0, last + 1)); - } - Bck2Brwsr b2b = Bck2Brwsr.newCompiler(). - resources(new EmulationResources() { - @Override - public InputStream get(String name) throws IOException { - if (name.equals(resourceName)) { - return new ByteArrayInputStream(resourceContent.getBytes("UTF-8")); - } - return super.get(name); - } - }). - addClasses(names). - addResources("org/apidesign/vm4brwsr/obj.js"). - addExported(exp.toArray(new String[0])). - obfuscation(ObfuscationLevel.FULL). - library(); - if (resourceName != null) { - b2b = b2b.addResources(resourceName); - } - b2b.generate(sb); - try { - defineAtoB(eng[0]); - Object res = eng[0].eval(sb.toString()); - assertTrue(eng[0] instanceof Invocable, "It is invocable object: " + res); - return new TestVM((Invocable) eng[0], sb); - } catch (Exception ex) { - if (sb.length() > 2000) { - sb = dumpJS(sb); - } - fail("Could not evaluate:" + ex.getClass() + ":" + ex.getMessage() + "\n" + sb, ex); - return null; - } - } - - static TestVM compileClassAndResources(StringBuilder sb, ScriptEngine[] eng, String name, String... resources) throws ScriptException, IOException { - if (sb == null) { - sb = new StringBuilder(); - } - Bck2Brwsr b2b = Bck2Brwsr.newCompiler(). - resources(new EmulationResources()). - addRootClasses(name). - addResources(resources); - b2b.generate(sb); - ScriptEngineManager sem = new ScriptEngineManager(); - ScriptEngine js = sem.getEngineByExtension("js"); - if (eng != null) { - eng[0] = js; - } - try { - defineAtoB(js); - - Object res = js.eval(sb.toString()); - assertTrue(js instanceof Invocable, "It is invocable object: " + res); - return new TestVM((Invocable) js, sb); - } catch (Exception ex) { - if (sb.length() > 2000) { - sb = dumpJS(sb); - } - fail("Could not evaluate:" + ex.getClass() + ":" + ex.getMessage() + "\n" + sb, ex); - return null; - } - } - - private static void defineAtoB(ScriptEngine js) throws ScriptException { - js.eval("atob = function(s) { return new String(org.apidesign.vm4brwsr.ResourcesTest.parseBase64Binary(s)); }"); - } - - Object invokeMethod(Object obj, String method, Object... params) throws ScriptException, NoSuchMethodException { - return code.invokeMethod(obj, method, params); - } - - Object invokeFunction(String methodName, Object... args) throws ScriptException, NoSuchMethodException { - return code.invokeFunction(methodName, args); - } - - static StringBuilder dumpJS(CharSequence sb) throws IOException { - File f = File.createTempFile("execution", ".js"); - FileWriter w = new FileWriter(f); - w.append(sb); - w.close(); - return new StringBuilder(f.getPath()); - } - - @Override - public String toString() { - try { - return dumpJS(codeSeq).toString(); - } catch (IOException ex) { - return ex.toString(); - } - } - - final CharSequence codeSeq() { - return codeSeq; - } - - private static class EmulationResources implements Bck2Brwsr.Resources { - @Override - public InputStream get(String name) throws IOException { - if ("java/net/URI.class".equals(name)) { - // skip - return null; - } - if ("java/net/URLConnection.class".equals(name)) { - // skip - return null; - } - if ("java/lang/System.class".equals(name)) { - // skip - return null; - } - Enumeration en = TestVM.class.getClassLoader().getResources(name); - URL u = null; - while (en.hasMoreElements()) { - u = en.nextElement(); - } - if (u == null) { - throw new IOException("Can't find " + name); - } - if (u.toExternalForm().contains("rt.jar!")) { - throw new IOException("No emulation for " + u); - } - return u.openStream(); - } - } -} diff -r bd151459ee4f -r da24a2411ee7 rt/vm8/pom.xml --- a/rt/vm8/pom.xml Sun Aug 10 07:02:12 2014 +0200 +++ b/rt/vm8/pom.xml Sun Aug 10 07:12:30 2014 +0200 @@ -35,5 +35,12 @@ test jar + + org.ow2.asm + asm-debug-all + 4.1 + test + jar + \ No newline at end of file diff -r bd151459ee4f -r da24a2411ee7 rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/InvokeDynamic.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/InvokeDynamic.java Sun Aug 10 07:12:30 2014 +0200 @@ -0,0 +1,46 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.vm8; + +import java.lang.invoke.CallSite; +import java.lang.invoke.ConstantCallSite; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class InvokeDynamic { + + public static String dynamicSay() { + return TEST_dynamic_boot1(new InvokeDynamic()); + } + + private static String TEST_dynamic_boot1(InvokeDynamic instance) { + throw new IllegalStateException("Can't touch this"); + } + + public static CallSite boot1(MethodHandles.Lookup lookup, String name, MethodType type) { + try { + return new ConstantCallSite(lookup.findVirtual(InvokeDynamic.class, "instance_sayHello", MethodType.methodType(String.class))); + } catch (NoSuchMethodException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + + public String instance_sayHello() { + return "Hello from Dynamic!"; + } +} \ No newline at end of file diff -r bd151459ee4f -r da24a2411ee7 rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/InvokeDynamicTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/InvokeDynamicTest.java Sun Aug 10 07:12:30 2014 +0200 @@ -0,0 +1,183 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.vm8; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.invoke.CallSite; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.Enumeration; +import org.apidesign.vm4brwsr.Bck2Brwsr; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Handle; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import static org.objectweb.asm.Opcodes.ASM4; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; +import static org.testng.Assert.*; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class InvokeDynamicTest { + private static Class invokeDynamicClass; + private static byte[] invokeDynamicBytes; + private static TestVM code; + + @Test public void simpleDynamicInJava() throws Exception { + Method m = invokeDynamicClass.getMethod("dynamicSay"); + Object ret = m.invoke(m); + assertEquals(ret, "Hello from Dynamic!"); + } + + @Test public void simpleDynamicInJS() throws Exception { + code.assertExec( + "Invoke dynamic can return a value", InvokeDynamic.class, + "dynamic__Ljava_lang_String_2", + "Hello from Dynamic!" + ); + } + + + @AfterClass + public static void releaseTheCode() { + code = null; + } + + // + // the following code is inspired by + // https://code.google.com/p/indy-maven-plugin/ + // which I don't want to use, as it is not in a public repository + // + @BeforeClass + public static void prepareClass() throws Exception { + InputStream is = InvokeDynamic.class.getResourceAsStream("InvokeDynamic.class"); + assertNotNull(is, "Class found"); + + ClassReader reader = new ClassReader(is) { + @Override + public short readShort(int index) { + if (index == 6) { + return Opcodes.V1_7; + } + return super.readShort(index); + } + }; + ClassWriter writer = new ClassWriter(reader, 0); + + reader.accept( + new ClassVisitor(ASM4, writer) { + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions + ) { + MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); + return new InvokeDynamicProcessor(mv); + } + }, + 0); + is.close(); + invokeDynamicBytes = writer.toByteArray(); + ClassLoader l = new ClassLoader() { + @Override + public Class loadClass(String name) throws ClassNotFoundException { + if (name.equals(InvokeDynamic.class.getName())) { + return defineClass(name, invokeDynamicBytes, 0, invokeDynamicBytes.length); + } + return super.loadClass(name); + } + }; + invokeDynamicClass = l.loadClass(InvokeDynamic.class.getName()); + + code = TestVM.compileClass( + null, null, new EmulationResourcesWithException(), + InvokeDynamic.class.getName().replace('.', '/') + ); + } + + + private static class InvokeDynamicProcessor extends MethodVisitor { + InvokeDynamicProcessor(MethodVisitor mv) { + super(ASM4, mv); + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc) { + if (opcode == INVOKESTATIC) { + if (name.startsWith("TEST_dynamic_")) { + final String shortName = name.substring(13); + Handle mh = new Handle( + Opcodes.H_INVOKESTATIC, owner, shortName, + MethodType.methodType( + CallSite.class, + MethodHandles.Lookup.class, + String.class, + MethodType.class + ).toMethodDescriptorString() + ); + super.visitInvokeDynamicInsn(shortName, desc, mh); + return; + } + } + super.visitMethodInsn(opcode, owner, name, desc); + } + } + + private static class EmulationResourcesWithException implements Bck2Brwsr.Resources { + @Override + public InputStream get(String name) throws IOException { + if ("org/apidesign/vm4brwsr/InvokeDynamic.class".equals(name)) { + return new ByteArrayInputStream(invokeDynamicBytes); + } + if ("java/net/URI.class".equals(name)) { + // skip + return null; + } + if ("java/net/URLConnection.class".equals(name)) { + // skip + return null; + } + if ("java/lang/System.class".equals(name)) { + // skip + return null; + } + Enumeration en = InvokeDynamicTest.class.getClassLoader().getResources(name); + URL u = null; + while (en.hasMoreElements()) { + u = en.nextElement(); + } + if (u == null) { + throw new IOException("Can't find " + name); + } + if (u.toExternalForm().contains("rt.jar!")) { + throw new IOException("No emulation for " + u); + } + return u.openStream(); + } + } + +} diff -r bd151459ee4f -r da24a2411ee7 rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/TestVM.java --- a/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/TestVM.java Sun Aug 10 07:02:12 2014 +0200 +++ b/rt/vm8/src/test/java/org/apidesign/bck2brwsr/vm8/TestVM.java Sun Aug 10 07:12:30 2014 +0200 @@ -125,10 +125,16 @@ } static TestVM compileClass(StringBuilder sb, ScriptEngine[] eng, String... names) throws ScriptException, IOException { + return compileClass(sb, eng, new EmulationResources(), names); + } + static TestVM compileClass( + StringBuilder sb, ScriptEngine[] eng, + Bck2Brwsr.Resources resources, String... names + ) throws ScriptException, IOException { if (sb == null) { sb = new StringBuilder(); } - Bck2Brwsr.generate(sb, new EmulationResources(), names); + Bck2Brwsr.generate(sb, resources, names); ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine js = sem.getEngineByExtension("js"); if (eng != null) {