# HG changeset patch # User Jaroslav Tulach # Date 1407649969 -7200 # Node ID 78485949d340c22e19c5660f5e32e1f0a4949617 # Parent da24a2411ee76492c92b8a8f8c4a58d3e8656542 All modules, except the one that deals with invokeDynamic pass OK diff -r da24a2411ee7 -r 78485949d340 rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Aug 10 07:12:30 2014 +0200 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Aug 10 07:52:49 2014 +0200 @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; +import org.apidesign.bck2brwsr.core.JavaScriptBody; import static org.apidesign.vm4brwsr.ByteCodeParser.*; /** Translator of the code inside class files to JavaScript. @@ -1053,10 +1054,10 @@ break; case opc_invokedynamic: { int indx = readUShortArg(byteCodes, i); - System.err.println("invoke dynamic: " + indx); + println("invoke dynamic: " + indx); ByteCodeParser.CPX2 c2 = jc.getCpoolEntry(indx); - System.err.println(" bootmethod: " + jc.getBootMethod(c2.cpx1)); - System.err.println(" name and type: " + jc.stringValue(c2.cpx2, true)); + println(" bootmethod: " + jc.getBootMethod(c2.cpx1)); + println(" name and type: " + jc.stringValue(c2.cpx2, true)); emit(smapper, this, "throw 'Invoke dynamic: ' + @1;", "" + indx); i += 4; break; @@ -2317,4 +2318,9 @@ append(Integer.toString(cc)); } } + + @JavaScriptBody(args = "msg", body = "") + private static void println(String msg) { + System.err.println(msg); + } } diff -r da24a2411ee7 -r 78485949d340 rt/vm/src/test/java/org/apidesign/vm4brwsr/InvokeDynamic.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/InvokeDynamic.java Sun Aug 10 07:12:30 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; - -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 da24a2411ee7 -r 78485949d340 rt/vm/src/test/java/org/apidesign/vm4brwsr/InvokeDynamicTest.java --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/InvokeDynamicTest.java Sun Aug 10 07:12:30 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,174 +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; - -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.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(); - } - } - -}