1.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Aug 10 07:12:30 2014 +0200
1.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Aug 10 07:52:49 2014 +0200
1.3 @@ -19,6 +19,7 @@
1.4
1.5 import java.io.IOException;
1.6 import java.io.InputStream;
1.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
1.8 import static org.apidesign.vm4brwsr.ByteCodeParser.*;
1.9
1.10 /** Translator of the code inside class files to JavaScript.
1.11 @@ -1053,10 +1054,10 @@
1.12 break;
1.13 case opc_invokedynamic: {
1.14 int indx = readUShortArg(byteCodes, i);
1.15 - System.err.println("invoke dynamic: " + indx);
1.16 + println("invoke dynamic: " + indx);
1.17 ByteCodeParser.CPX2 c2 = jc.getCpoolEntry(indx);
1.18 - System.err.println(" bootmethod: " + jc.getBootMethod(c2.cpx1));
1.19 - System.err.println(" name and type: " + jc.stringValue(c2.cpx2, true));
1.20 + println(" bootmethod: " + jc.getBootMethod(c2.cpx1));
1.21 + println(" name and type: " + jc.stringValue(c2.cpx2, true));
1.22 emit(smapper, this, "throw 'Invoke dynamic: ' + @1;", "" + indx);
1.23 i += 4;
1.24 break;
1.25 @@ -2317,4 +2318,9 @@
1.26 append(Integer.toString(cc));
1.27 }
1.28 }
1.29 +
1.30 + @JavaScriptBody(args = "msg", body = "")
1.31 + private static void println(String msg) {
1.32 + System.err.println(msg);
1.33 + }
1.34 }
2.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/InvokeDynamic.java Sun Aug 10 07:12:30 2014 +0200
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,46 +0,0 @@
2.4 -/**
2.5 - * Back 2 Browser Bytecode Translator
2.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.7 - *
2.8 - * This program is free software: you can redistribute it and/or modify
2.9 - * it under the terms of the GNU General Public License as published by
2.10 - * the Free Software Foundation, version 2 of the License.
2.11 - *
2.12 - * This program is distributed in the hope that it will be useful,
2.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.15 - * GNU General Public License for more details.
2.16 - *
2.17 - * You should have received a copy of the GNU General Public License
2.18 - * along with this program. Look for COPYING file in the top folder.
2.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
2.20 - */
2.21 -package org.apidesign.vm4brwsr;
2.22 -
2.23 -import java.lang.invoke.CallSite;
2.24 -import java.lang.invoke.ConstantCallSite;
2.25 -import java.lang.invoke.MethodHandles;
2.26 -import java.lang.invoke.MethodType;
2.27 -
2.28 -public class InvokeDynamic {
2.29 -
2.30 - public static String dynamicSay() {
2.31 - return TEST_dynamic_boot1(new InvokeDynamic());
2.32 - }
2.33 -
2.34 - private static String TEST_dynamic_boot1(InvokeDynamic instance) {
2.35 - throw new IllegalStateException("Can't touch this");
2.36 - }
2.37 -
2.38 - public static CallSite boot1(MethodHandles.Lookup lookup, String name, MethodType type) {
2.39 - try {
2.40 - return new ConstantCallSite(lookup.findVirtual(InvokeDynamic.class, "instance_sayHello", MethodType.methodType(String.class)));
2.41 - } catch (NoSuchMethodException | IllegalAccessException e) {
2.42 - throw new IllegalStateException(e);
2.43 - }
2.44 - }
2.45 -
2.46 - public String instance_sayHello() {
2.47 - return "Hello from Dynamic!";
2.48 - }
2.49 -}
2.50 \ No newline at end of file
3.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/InvokeDynamicTest.java Sun Aug 10 07:12:30 2014 +0200
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,174 +0,0 @@
3.4 -/**
3.5 - * Back 2 Browser Bytecode Translator
3.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
3.7 - *
3.8 - * This program is free software: you can redistribute it and/or modify
3.9 - * it under the terms of the GNU General Public License as published by
3.10 - * the Free Software Foundation, version 2 of the License.
3.11 - *
3.12 - * This program is distributed in the hope that it will be useful,
3.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.15 - * GNU General Public License for more details.
3.16 - *
3.17 - * You should have received a copy of the GNU General Public License
3.18 - * along with this program. Look for COPYING file in the top folder.
3.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
3.20 - */
3.21 -package org.apidesign.vm4brwsr;
3.22 -
3.23 -import java.io.ByteArrayInputStream;
3.24 -import java.io.IOException;
3.25 -import java.io.InputStream;
3.26 -import java.lang.invoke.CallSite;
3.27 -import java.lang.invoke.MethodHandles;
3.28 -import java.lang.invoke.MethodType;
3.29 -import java.lang.reflect.Method;
3.30 -import java.net.URL;
3.31 -import java.util.Enumeration;
3.32 -import org.objectweb.asm.ClassReader;
3.33 -import org.objectweb.asm.ClassVisitor;
3.34 -import org.objectweb.asm.ClassWriter;
3.35 -import org.objectweb.asm.Handle;
3.36 -import org.objectweb.asm.MethodVisitor;
3.37 -import org.objectweb.asm.Opcodes;
3.38 -import static org.objectweb.asm.Opcodes.ASM4;
3.39 -import static org.objectweb.asm.Opcodes.INVOKESTATIC;
3.40 -import static org.testng.Assert.*;
3.41 -import org.testng.annotations.AfterClass;
3.42 -import org.testng.annotations.BeforeClass;
3.43 -import org.testng.annotations.Test;
3.44 -
3.45 -/**
3.46 - *
3.47 - * @author Jaroslav Tulach <jtulach@netbeans.org>
3.48 - */
3.49 -public class InvokeDynamicTest {
3.50 - private static Class<?> invokeDynamicClass;
3.51 - private static byte[] invokeDynamicBytes;
3.52 - private static TestVM code;
3.53 -
3.54 - @Test public void simpleDynamicInJava() throws Exception {
3.55 - Method m = invokeDynamicClass.getMethod("dynamicSay");
3.56 - Object ret = m.invoke(m);
3.57 - assertEquals(ret, "Hello from Dynamic!");
3.58 - }
3.59 -
3.60 - @Test public void simpleDynamicInJS() throws Exception {
3.61 - code.assertExec(
3.62 - "Invoke dynamic can return a value", InvokeDynamic.class,
3.63 - "dynamic__Ljava_lang_String_2",
3.64 - "Hello from Dynamic!"
3.65 - );
3.66 - }
3.67 -
3.68 -
3.69 - @AfterClass
3.70 - public static void releaseTheCode() {
3.71 - code = null;
3.72 - }
3.73 -
3.74 - //
3.75 - // the following code is inspired by
3.76 - // https://code.google.com/p/indy-maven-plugin/
3.77 - // which I don't want to use, as it is not in a public repository
3.78 - //
3.79 - @BeforeClass
3.80 - public static void prepareClass() throws Exception {
3.81 - InputStream is = InvokeDynamic.class.getResourceAsStream("InvokeDynamic.class");
3.82 - assertNotNull(is, "Class found");
3.83 -
3.84 - ClassReader reader = new ClassReader(is);
3.85 - ClassWriter writer = new ClassWriter(reader, 0);
3.86 -
3.87 - reader.accept(
3.88 - new ClassVisitor(ASM4, writer) {
3.89 - @Override
3.90 - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions
3.91 - ) {
3.92 - MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
3.93 - return new InvokeDynamicProcessor(mv);
3.94 - }
3.95 - },
3.96 - 0);
3.97 - is.close();
3.98 - invokeDynamicBytes = writer.toByteArray();
3.99 - ClassLoader l = new ClassLoader() {
3.100 - @Override
3.101 - public Class<?> loadClass(String name) throws ClassNotFoundException {
3.102 - if (name.equals(InvokeDynamic.class.getName())) {
3.103 - return defineClass(name, invokeDynamicBytes, 0, invokeDynamicBytes.length);
3.104 - }
3.105 - return super.loadClass(name);
3.106 - }
3.107 - };
3.108 - invokeDynamicClass = l.loadClass(InvokeDynamic.class.getName());
3.109 -
3.110 - code = TestVM.compileClass(
3.111 - null, null, new EmulationResourcesWithException(),
3.112 - InvokeDynamic.class.getName().replace('.', '/')
3.113 - );
3.114 - }
3.115 -
3.116 -
3.117 - private static class InvokeDynamicProcessor extends MethodVisitor {
3.118 - InvokeDynamicProcessor(MethodVisitor mv) {
3.119 - super(ASM4, mv);
3.120 - }
3.121 -
3.122 - @Override
3.123 - public void visitMethodInsn(int opcode, String owner, String name, String desc) {
3.124 - if (opcode == INVOKESTATIC) {
3.125 - if (name.startsWith("TEST_dynamic_")) {
3.126 - final String shortName = name.substring(13);
3.127 - Handle mh = new Handle(
3.128 - Opcodes.H_INVOKESTATIC, owner, shortName,
3.129 - MethodType.methodType(
3.130 - CallSite.class,
3.131 - MethodHandles.Lookup.class,
3.132 - String.class,
3.133 - MethodType.class
3.134 - ).toMethodDescriptorString()
3.135 - );
3.136 - super.visitInvokeDynamicInsn(shortName, desc, mh);
3.137 - return;
3.138 - }
3.139 - }
3.140 - super.visitMethodInsn(opcode, owner, name, desc);
3.141 - }
3.142 - }
3.143 -
3.144 - private static class EmulationResourcesWithException implements Bck2Brwsr.Resources {
3.145 - @Override
3.146 - public InputStream get(String name) throws IOException {
3.147 - if ("org/apidesign/vm4brwsr/InvokeDynamic.class".equals(name)) {
3.148 - return new ByteArrayInputStream(invokeDynamicBytes);
3.149 - }
3.150 - if ("java/net/URI.class".equals(name)) {
3.151 - // skip
3.152 - return null;
3.153 - }
3.154 - if ("java/net/URLConnection.class".equals(name)) {
3.155 - // skip
3.156 - return null;
3.157 - }
3.158 - if ("java/lang/System.class".equals(name)) {
3.159 - // skip
3.160 - return null;
3.161 - }
3.162 - Enumeration<URL> en = InvokeDynamicTest.class.getClassLoader().getResources(name);
3.163 - URL u = null;
3.164 - while (en.hasMoreElements()) {
3.165 - u = en.nextElement();
3.166 - }
3.167 - if (u == null) {
3.168 - throw new IOException("Can't find " + name);
3.169 - }
3.170 - if (u.toExternalForm().contains("rt.jar!")) {
3.171 - throw new IOException("No emulation for " + u);
3.172 - }
3.173 - return u.openStream();
3.174 - }
3.175 - }
3.176 -
3.177 -}