Creating Bck2Brwsr entrypoint to for those who wish to generate their JavaScript based Java VM
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Tue Dec 11 09:36:44 2012 +0100
1.3 @@ -0,0 +1,106 @@
1.4 +/**
1.5 + * Back 2 Browser Bytecode Translator
1.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
1.7 + *
1.8 + * This program is free software: you can redistribute it and/or modify
1.9 + * it under the terms of the GNU General Public License as published by
1.10 + * the Free Software Foundation, version 2 of the License.
1.11 + *
1.12 + * This program is distributed in the hope that it will be useful,
1.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.15 + * GNU General Public License for more details.
1.16 + *
1.17 + * You should have received a copy of the GNU General Public License
1.18 + * along with this program. Look for COPYING file in the top folder.
1.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
1.20 + */
1.21 +package org.apidesign.vm4brwsr;
1.22 +
1.23 +import java.io.IOException;
1.24 +import java.io.InputStream;
1.25 +import java.net.URL;
1.26 +import java.util.Enumeration;
1.27 +
1.28 +/** Build your own virtual machine! Use methods in this class to generate
1.29 + * a skeleton JVM in JavaScript that contains pre-compiled classes of your
1.30 + * choice. The generated script defines one JavaScript method that can
1.31 + * be used to bootstrap and load the virtual machine: <pre>
1.32 + * var vm = bck2brwsr();
1.33 + * var main = vm.loadClass('org.your.pkg.Main');
1.34 + * main.main__V_3Ljava_lang_String_2(null);
1.35 + * </pre>
1.36 + * In case one wants to initialize the virtual machine with ability to
1.37 + * load classes lazily when needed, one can provide a loader function to
1.38 + * when creating the virtual machine: <pre>
1.39 + * var vm = bck2brwsr(function(resource) {
1.40 + * return null; // byte[] for the resource
1.41 + * });
1.42 + * </pre>
1.43 + * In this scenario, when a request for a unknown class is made, the loader
1.44 + * function is asked for its byte code and the system dynamically transforms
1.45 + * it to JavaScript.
1.46 + *
1.47 + * @author Jaroslav Tulach <jtulach@netbeans.org>
1.48 + */
1.49 +public final class Bck2Brwsr {
1.50 + private Bck2Brwsr() {
1.51 + }
1.52 +
1.53 + /** Generates virtual machine from bytes served by a <code>resources</code>
1.54 + * provider.
1.55 + *
1.56 + * @param out the output to write the generated JavaScript to
1.57 + * @param resources provider of class files to use
1.58 + * @param classes additional classes to include in the generated script
1.59 + * @throws IOException I/O exception can be thrown when something goes wrong
1.60 + */
1.61 + public static void generate(Appendable out, Resources resources, String... classes) throws IOException {
1.62 + StringArray arr = StringArray.asList(classes);
1.63 + arr.add(VM.class.getName().replace('.', '/'));
1.64 + VM.compile(resources, out, arr);
1.65 + }
1.66 +
1.67 + /** Generates virtual machine from bytes served by a class loader.
1.68 + *
1.69 + * @param out the output to write the generated JavaScript to
1.70 + * @param loader class loader to load needed classes from
1.71 + * @param classes additional classes to include in the generated script
1.72 + * @throws IOException I/O exception can be thrown when something goes wrong
1.73 + */
1.74 + public static void generate(Appendable out, final ClassLoader loader, String... classes) throws IOException {
1.75 + class R implements Resources {
1.76 + @Override
1.77 + public InputStream get(String name) throws IOException {
1.78 + Enumeration<URL> en = loader.getResources(name);
1.79 + URL u = null;
1.80 + while (en.hasMoreElements()) {
1.81 + u = en.nextElement();
1.82 + }
1.83 + if (u == null) {
1.84 + throw new IOException("Can't find " + name);
1.85 + }
1.86 + return u.openStream();
1.87 + }
1.88 + }
1.89 + generate(out, new R(), classes);
1.90 + }
1.91 +
1.92 + /** Provider of resources (classes and other files). The
1.93 + * {@link #generate(java.lang.Appendable, org.apidesign.vm4brwsr.Bck2Brwsr.Resources, java.lang.String[])
1.94 + * generator method} will call back here for all classes needed during
1.95 + * translation to JavaScript.
1.96 + */
1.97 + public interface Resources {
1.98 + /** Loads given resource (class or other file like image). The
1.99 + * resource name to load bytes for the {@link String} class
1.100 + * would be <code>"java/lang/String.class"</code>.
1.101 + *
1.102 + * @param resource path to resource to load
1.103 + * @return the input stream for the resource
1.104 + * @throws IOException can be thrown if the loading fails on some error
1.105 + * or the file cannot be found
1.106 + */
1.107 + public InputStream get(String resource) throws IOException;
1.108 + }
1.109 +}
2.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Dec 07 14:10:37 2012 +0100
2.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Dec 11 09:36:44 2012 +0100
2.3 @@ -29,7 +29,7 @@
2.4 *
2.5 * @author Jaroslav Tulach <jtulach@netbeans.org>
2.6 */
2.7 -public abstract class ByteCodeToJavaScript {
2.8 +abstract class ByteCodeToJavaScript {
2.9 private ClassData jc;
2.10 final Appendable out;
2.11
3.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/GenJS.java Fri Dec 07 14:10:37 2012 +0100
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,229 +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.IOException;
3.24 -import java.io.InputStream;
3.25 -import java.net.URL;
3.26 -import java.util.Enumeration;
3.27 -
3.28 -/** Generator of JavaScript from bytecode of classes on classpath of the VM.
3.29 - *
3.30 - * @author Jaroslav Tulach <jtulach@netbeans.org>
3.31 - */
3.32 -class GenJS extends ByteCodeToJavaScript {
3.33 - public GenJS(Appendable out) {
3.34 - super(out);
3.35 - }
3.36 -
3.37 - static {
3.38 - // uses VMLazy to load dynamic classes
3.39 - VMLazy.init();
3.40 - }
3.41 -
3.42 - static void compile(Appendable out, String... names) throws IOException {
3.43 - compile(out, StringArray.asList(names));
3.44 - }
3.45 - static void compile(ClassLoader l, Appendable out, String... names) throws IOException {
3.46 - compile(l, out, StringArray.asList(names));
3.47 - }
3.48 - static void compile(Appendable out, StringArray names) throws IOException {
3.49 - compile(GenJS.class.getClassLoader(), out, names);
3.50 - }
3.51 - static void compile(ClassLoader l, Appendable out, StringArray names) throws IOException {
3.52 - new GenJS(out).doCompile(l, names);
3.53 - }
3.54 - protected void doCompile(ClassLoader l, StringArray names) throws IOException {
3.55 - out.append("(function VM(global) {");
3.56 - out.append("\n var vm = {};");
3.57 - StringArray processed = new StringArray();
3.58 - StringArray initCode = new StringArray();
3.59 - for (String baseClass : names.toArray()) {
3.60 - references.add(baseClass);
3.61 - for (;;) {
3.62 - String name = null;
3.63 - for (String n : references.toArray()) {
3.64 - if (processed.contains(n)) {
3.65 - continue;
3.66 - }
3.67 - name = n;
3.68 - }
3.69 - if (name == null) {
3.70 - break;
3.71 - }
3.72 - InputStream is = loadClass(l, name);
3.73 - if (is == null) {
3.74 - throw new IOException("Can't find class " + name);
3.75 - }
3.76 - try {
3.77 - String ic = compile(is);
3.78 - processed.add(name);
3.79 - initCode.add(ic == null ? "" : ic);
3.80 - } catch (RuntimeException ex) {
3.81 - if (out instanceof CharSequence) {
3.82 - CharSequence seq = (CharSequence)out;
3.83 - int lastBlock = seq.length();
3.84 - while (lastBlock-- > 0) {
3.85 - if (seq.charAt(lastBlock) == '{') {
3.86 - break;
3.87 - }
3.88 - }
3.89 - throw new IOException("Error while compiling " + name + "\n"
3.90 - + seq.subSequence(lastBlock + 1, seq.length()), ex
3.91 - );
3.92 - } else {
3.93 - throw new IOException("Error while compiling " + name + "\n"
3.94 - + out, ex
3.95 - );
3.96 - }
3.97 - }
3.98 - }
3.99 -
3.100 - for (String resource : scripts.toArray()) {
3.101 - while (resource.startsWith("/")) {
3.102 - resource = resource.substring(1);
3.103 - }
3.104 - InputStream emul = l.getResourceAsStream(resource);
3.105 - if (emul == null) {
3.106 - throw new IOException("Can't find " + resource);
3.107 - }
3.108 - readResource(emul, out);
3.109 - }
3.110 - scripts = new StringArray();
3.111 -
3.112 - StringArray toInit = StringArray.asList(references.toArray());
3.113 - toInit.reverse();
3.114 -
3.115 - for (String ic : toInit.toArray()) {
3.116 - int indx = processed.indexOf(ic);
3.117 - if (indx >= 0) {
3.118 - out.append(initCode.toArray()[indx]).append("\n");
3.119 - initCode.toArray()[indx] = "";
3.120 - }
3.121 - }
3.122 - }
3.123 - out.append(
3.124 - " global.bck2brwsr = function() {\n"
3.125 - + " var args = arguments;\n"
3.126 - + " var loader = {};\n"
3.127 - + " loader.vm = vm;\n"
3.128 - + " loader.loadClass = function(name) {\n"
3.129 - + " var attr = name.replace__Ljava_lang_String_2CC(name, '.','_');\n"
3.130 - + " var fn = vm[attr];\n"
3.131 - + " if (fn) return fn(false);\n"
3.132 - + " return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
3.133 - + " load___3Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
3.134 - + " }\n"
3.135 - + " return loader;\n"
3.136 - + " };\n");
3.137 - out.append("}(this));");
3.138 - }
3.139 - private static void readResource(InputStream emul, Appendable out) throws IOException {
3.140 - try {
3.141 - int state = 0;
3.142 - for (;;) {
3.143 - int ch = emul.read();
3.144 - if (ch == -1) {
3.145 - break;
3.146 - }
3.147 - if (ch < 0 || ch > 255) {
3.148 - throw new IOException("Invalid char in emulation " + ch);
3.149 - }
3.150 - switch (state) {
3.151 - case 0:
3.152 - if (ch == '/') {
3.153 - state = 1;
3.154 - } else {
3.155 - out.append((char)ch);
3.156 - }
3.157 - break;
3.158 - case 1:
3.159 - if (ch == '*') {
3.160 - state = 2;
3.161 - } else {
3.162 - out.append('/').append((char)ch);
3.163 - state = 0;
3.164 - }
3.165 - break;
3.166 - case 2:
3.167 - if (ch == '*') {
3.168 - state = 3;
3.169 - }
3.170 - break;
3.171 - case 3:
3.172 - if (ch == '/') {
3.173 - state = 0;
3.174 - } else {
3.175 - state = 2;
3.176 - }
3.177 - break;
3.178 - }
3.179 - }
3.180 - } finally {
3.181 - emul.close();
3.182 - }
3.183 - }
3.184 -
3.185 - private static InputStream loadClass(ClassLoader l, String name) throws IOException {
3.186 - Enumeration<URL> en = l.getResources(name + ".class");
3.187 - URL u = null;
3.188 - while (en.hasMoreElements()) {
3.189 - u = en.nextElement();
3.190 - }
3.191 - if (u == null) {
3.192 - throw new IOException("Can't find " + name);
3.193 - }
3.194 - if (u.toExternalForm().contains("rt.jar!")) {
3.195 - throw new IOException("No emulation for " + u);
3.196 - }
3.197 - return u.openStream();
3.198 - }
3.199 -
3.200 - static String toString(String name) throws IOException {
3.201 - StringBuilder sb = new StringBuilder();
3.202 - compile(sb, name);
3.203 - return sb.toString().toString();
3.204 - }
3.205 -
3.206 - private StringArray scripts = new StringArray();
3.207 - private StringArray references = new StringArray();
3.208 -
3.209 - @Override
3.210 - protected boolean requireReference(String cn) {
3.211 - if (references.contains(cn)) {
3.212 - return false;
3.213 - }
3.214 - references.add(cn);
3.215 - return true;
3.216 - }
3.217 -
3.218 - @Override
3.219 - protected void requireScript(String resourcePath) {
3.220 - scripts.add(resourcePath);
3.221 - }
3.222 -
3.223 - @Override
3.224 - String assignClass(String className) {
3.225 - return "vm." + className + " = ";
3.226 - }
3.227 -
3.228 - @Override
3.229 - String accessClass(String className) {
3.230 - return "vm." + className;
3.231 - }
3.232 -}
4.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/Main.java Fri Dec 07 14:10:37 2012 +0100
4.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Main.java Tue Dec 11 09:36:44 2012 +0100
4.3 @@ -32,6 +32,7 @@
4.4
4.5 public static void main(String... args) throws IOException {
4.6 if (args.length < 2) {
4.7 + System.err.println("Bck2Brwsr Translator from Java(tm) to JavaScript, (c) Jaroslav Tulach 2012");
4.8 System.err.println("Usage: java -cp ... -jar ... <file_to_generate_js_code_to> java/lang/Class org/your/App ...");
4.9 return;
4.10 }
4.11 @@ -39,7 +40,7 @@
4.12 Writer w = new BufferedWriter(new FileWriter(args[0]));
4.13 StringArray classes = StringArray.asList(args);
4.14 classes.delete(0);
4.15 - GenJS.compile(w, classes);
4.16 + Bck2Brwsr.generate(w, Main.class.getClassLoader(), classes.toArray());
4.17 w.close();
4.18 }
4.19 }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Tue Dec 11 09:36:44 2012 +0100
5.3 @@ -0,0 +1,207 @@
5.4 +/**
5.5 + * Back 2 Browser Bytecode Translator
5.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.7 + *
5.8 + * This program is free software: you can redistribute it and/or modify
5.9 + * it under the terms of the GNU General Public License as published by
5.10 + * the Free Software Foundation, version 2 of the License.
5.11 + *
5.12 + * This program is distributed in the hope that it will be useful,
5.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.15 + * GNU General Public License for more details.
5.16 + *
5.17 + * You should have received a copy of the GNU General Public License
5.18 + * along with this program. Look for COPYING file in the top folder.
5.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
5.20 + */
5.21 +package org.apidesign.vm4brwsr;
5.22 +
5.23 +import java.io.IOException;
5.24 +import java.io.InputStream;
5.25 +
5.26 +/** Generator of JavaScript from bytecode of classes on classpath of the VM.
5.27 + *
5.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
5.29 + */
5.30 +class VM extends ByteCodeToJavaScript {
5.31 + public VM(Appendable out) {
5.32 + super(out);
5.33 + }
5.34 +
5.35 + static {
5.36 + // uses VMLazy to load dynamic classes
5.37 + VMLazy.init();
5.38 + }
5.39 +
5.40 + static void compile(Bck2Brwsr.Resources l, Appendable out, StringArray names) throws IOException {
5.41 + new VM(out).doCompile(l, names);
5.42 + }
5.43 + protected void doCompile(Bck2Brwsr.Resources l, StringArray names) throws IOException {
5.44 + out.append("(function VM(global) {");
5.45 + out.append("\n var vm = {};");
5.46 + StringArray processed = new StringArray();
5.47 + StringArray initCode = new StringArray();
5.48 + for (String baseClass : names.toArray()) {
5.49 + references.add(baseClass);
5.50 + for (;;) {
5.51 + String name = null;
5.52 + for (String n : references.toArray()) {
5.53 + if (processed.contains(n)) {
5.54 + continue;
5.55 + }
5.56 + name = n;
5.57 + }
5.58 + if (name == null) {
5.59 + break;
5.60 + }
5.61 + InputStream is = loadClass(l, name);
5.62 + if (is == null) {
5.63 + throw new IOException("Can't find class " + name);
5.64 + }
5.65 + try {
5.66 + String ic = compile(is);
5.67 + processed.add(name);
5.68 + initCode.add(ic == null ? "" : ic);
5.69 + } catch (RuntimeException ex) {
5.70 + if (out instanceof CharSequence) {
5.71 + CharSequence seq = (CharSequence)out;
5.72 + int lastBlock = seq.length();
5.73 + while (lastBlock-- > 0) {
5.74 + if (seq.charAt(lastBlock) == '{') {
5.75 + break;
5.76 + }
5.77 + }
5.78 + throw new IOException("Error while compiling " + name + "\n"
5.79 + + seq.subSequence(lastBlock + 1, seq.length()), ex
5.80 + );
5.81 + } else {
5.82 + throw new IOException("Error while compiling " + name + "\n"
5.83 + + out, ex
5.84 + );
5.85 + }
5.86 + }
5.87 + }
5.88 +
5.89 + for (String resource : scripts.toArray()) {
5.90 + while (resource.startsWith("/")) {
5.91 + resource = resource.substring(1);
5.92 + }
5.93 + InputStream emul = l.get(resource);
5.94 + if (emul == null) {
5.95 + throw new IOException("Can't find " + resource);
5.96 + }
5.97 + readResource(emul, out);
5.98 + }
5.99 + scripts = new StringArray();
5.100 +
5.101 + StringArray toInit = StringArray.asList(references.toArray());
5.102 + toInit.reverse();
5.103 +
5.104 + for (String ic : toInit.toArray()) {
5.105 + int indx = processed.indexOf(ic);
5.106 + if (indx >= 0) {
5.107 + out.append(initCode.toArray()[indx]).append("\n");
5.108 + initCode.toArray()[indx] = "";
5.109 + }
5.110 + }
5.111 + }
5.112 + out.append(
5.113 + " global.bck2brwsr = function() {\n"
5.114 + + " var args = arguments;\n"
5.115 + + " var loader = {};\n"
5.116 + + " loader.vm = vm;\n"
5.117 + + " loader.loadClass = function(name) {\n"
5.118 + + " var attr = name.replace__Ljava_lang_String_2CC(name, '.','_');\n"
5.119 + + " var fn = vm[attr];\n"
5.120 + + " if (fn) return fn(false);\n"
5.121 + + " return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
5.122 + + " load___3Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
5.123 + + " }\n"
5.124 + + " return loader;\n"
5.125 + + " };\n");
5.126 + out.append("}(this));");
5.127 + }
5.128 + private static void readResource(InputStream emul, Appendable out) throws IOException {
5.129 + try {
5.130 + int state = 0;
5.131 + for (;;) {
5.132 + int ch = emul.read();
5.133 + if (ch == -1) {
5.134 + break;
5.135 + }
5.136 + if (ch < 0 || ch > 255) {
5.137 + throw new IOException("Invalid char in emulation " + ch);
5.138 + }
5.139 + switch (state) {
5.140 + case 0:
5.141 + if (ch == '/') {
5.142 + state = 1;
5.143 + } else {
5.144 + out.append((char)ch);
5.145 + }
5.146 + break;
5.147 + case 1:
5.148 + if (ch == '*') {
5.149 + state = 2;
5.150 + } else {
5.151 + out.append('/').append((char)ch);
5.152 + state = 0;
5.153 + }
5.154 + break;
5.155 + case 2:
5.156 + if (ch == '*') {
5.157 + state = 3;
5.158 + }
5.159 + break;
5.160 + case 3:
5.161 + if (ch == '/') {
5.162 + state = 0;
5.163 + } else {
5.164 + state = 2;
5.165 + }
5.166 + break;
5.167 + }
5.168 + }
5.169 + } finally {
5.170 + emul.close();
5.171 + }
5.172 + }
5.173 +
5.174 + private static InputStream loadClass(Bck2Brwsr.Resources l, String name) throws IOException {
5.175 + return l.get(name + ".class"); // NOI18N
5.176 + }
5.177 +
5.178 + static String toString(String name) throws IOException {
5.179 + StringBuilder sb = new StringBuilder();
5.180 +// compile(sb, name);
5.181 + return sb.toString().toString();
5.182 + }
5.183 +
5.184 + private StringArray scripts = new StringArray();
5.185 + private StringArray references = new StringArray();
5.186 +
5.187 + @Override
5.188 + protected boolean requireReference(String cn) {
5.189 + if (references.contains(cn)) {
5.190 + return false;
5.191 + }
5.192 + references.add(cn);
5.193 + return true;
5.194 + }
5.195 +
5.196 + @Override
5.197 + protected void requireScript(String resourcePath) {
5.198 + scripts.add(resourcePath);
5.199 + }
5.200 +
5.201 + @Override
5.202 + String assignClass(String className) {
5.203 + return "vm." + className + " = ";
5.204 + }
5.205 +
5.206 + @Override
5.207 + String accessClass(String className) {
5.208 + return "vm." + className;
5.209 + }
5.210 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/BytesLoader.java Tue Dec 11 09:36:44 2012 +0100
6.3 @@ -0,0 +1,58 @@
6.4 +/**
6.5 + * Back 2 Browser Bytecode Translator
6.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
6.7 + *
6.8 + * This program is free software: you can redistribute it and/or modify
6.9 + * it under the terms of the GNU General Public License as published by
6.10 + * the Free Software Foundation, version 2 of the License.
6.11 + *
6.12 + * This program is distributed in the hope that it will be useful,
6.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.15 + * GNU General Public License for more details.
6.16 + *
6.17 + * You should have received a copy of the GNU General Public License
6.18 + * along with this program. Look for COPYING file in the top folder.
6.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
6.20 + */
6.21 +package org.apidesign.vm4brwsr;
6.22 +
6.23 +import java.io.IOException;
6.24 +import java.io.InputStream;
6.25 +import java.util.Set;
6.26 +import java.util.TreeSet;
6.27 +
6.28 +/**
6.29 + *
6.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
6.31 + */
6.32 +public final class BytesLoader {
6.33 + private static Set<String> requested = new TreeSet<String>();
6.34 +
6.35 + public byte[] get(String name) throws IOException {
6.36 + if (!requested.add(name)) {
6.37 + throw new IllegalStateException("Requested for second time: " + name);
6.38 + }
6.39 + InputStream is = BytesLoader.class.getClassLoader().getResourceAsStream(name);
6.40 + if (is == null) {
6.41 + throw new IOException("Can't find " + name);
6.42 + }
6.43 + byte[] arr = new byte[is.available()];
6.44 + int len = is.read(arr);
6.45 + if (len != arr.length) {
6.46 + throw new IOException("Read only " + len + " wanting " + arr.length);
6.47 + }
6.48 + /*
6.49 + System.err.print("loader['" + name + "'] = [");
6.50 + for (int i = 0; i < arr.length; i++) {
6.51 + if (i > 0) {
6.52 + System.err.print(", ");
6.53 + }
6.54 + System.err.print(arr[i]);
6.55 + }
6.56 + System.err.println("]");
6.57 + */
6.58 + return arr;
6.59 + }
6.60 +
6.61 +}
7.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/CompareVMs.java Fri Dec 07 14:10:37 2012 +0100
7.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/CompareVMs.java Tue Dec 11 09:36:44 2012 +0100
7.3 @@ -19,6 +19,7 @@
7.4
7.5 import java.lang.reflect.Method;
7.6 import javax.script.Invocable;
7.7 +import javax.script.ScriptContext;
7.8 import javax.script.ScriptEngine;
7.9 import javax.script.ScriptEngineManager;
7.10 import org.testng.Assert;
7.11 @@ -98,26 +99,11 @@
7.12 return;
7.13 }
7.14 StringBuilder sb = new StringBuilder();
7.15 - class SkipMe extends GenJS {
7.16 -
7.17 - public SkipMe(Appendable out) {
7.18 - super(out);
7.19 - }
7.20 -
7.21 - @Override
7.22 - protected boolean requireReference(String cn) {
7.23 - if (cn.contains("CompareVMs")) {
7.24 - return true;
7.25 - }
7.26 - return super.requireReference(cn);
7.27 - }
7.28 - }
7.29 - SkipMe sm = new SkipMe(sb);
7.30 - sm.doCompile(CompareVMs.class.getClassLoader(), StringArray.asList(
7.31 - clazz.getName().replace('.', '/')));
7.32 + Bck2Brwsr.generate(sb, CompareVMs.class.getClassLoader());
7.33
7.34 ScriptEngineManager sem = new ScriptEngineManager();
7.35 ScriptEngine js = sem.getEngineByExtension("js");
7.36 + js.getContext().setAttribute("loader", new BytesLoader(), ScriptContext.ENGINE_SCOPE);
7.37
7.38 Object res = js.eval(sb.toString());
7.39 Assert.assertTrue(js instanceof Invocable, "It is invocable object: " + res);
8.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Fri Dec 07 14:10:37 2012 +0100
8.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Tue Dec 11 09:36:44 2012 +0100
8.3 @@ -20,6 +20,9 @@
8.4 import java.io.File;
8.5 import java.io.FileWriter;
8.6 import java.io.IOException;
8.7 +import java.io.InputStream;
8.8 +import java.net.URL;
8.9 +import java.util.Enumeration;
8.10 import javax.script.Invocable;
8.11 import javax.script.ScriptEngine;
8.12 import javax.script.ScriptEngineManager;
8.13 @@ -289,7 +292,7 @@
8.14 if (sb == null) {
8.15 sb = new StringBuilder();
8.16 }
8.17 - GenJS.compile(sb, names);
8.18 + Bck2Brwsr.generate(sb, new EmulationResources(), names);
8.19 ScriptEngineManager sem = new ScriptEngineManager();
8.20 ScriptEngine js = sem.getEngineByExtension("js");
8.21 if (eng != null) {
8.22 @@ -314,4 +317,21 @@
8.23 w.close();
8.24 return new StringBuilder(f.getPath());
8.25 }
8.26 + private static class EmulationResources implements Bck2Brwsr.Resources {
8.27 + @Override
8.28 + public InputStream get(String name) throws IOException {
8.29 + Enumeration<URL> en = StaticMethodTest.class.getClassLoader().getResources(name);
8.30 + URL u = null;
8.31 + while (en.hasMoreElements()) {
8.32 + u = en.nextElement();
8.33 + }
8.34 + if (u == null) {
8.35 + throw new IOException("Can't find " + name);
8.36 + }
8.37 + if (u.toExternalForm().contains("rt.jar!")) {
8.38 + throw new IOException("No emulation for " + u);
8.39 + }
8.40 + return u.openStream();
8.41 + }
8.42 + }
8.43 }
9.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java Fri Dec 07 14:10:37 2012 +0100
9.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/VMLazyTest.java Tue Dec 11 09:36:44 2012 +0100
9.3 @@ -17,10 +17,6 @@
9.4 */
9.5 package org.apidesign.vm4brwsr;
9.6
9.7 -import java.io.IOException;
9.8 -import java.io.InputStream;
9.9 -import java.util.Set;
9.10 -import java.util.TreeSet;
9.11 import javax.script.Invocable;
9.12 import javax.script.ScriptContext;
9.13 import javax.script.ScriptEngine;
9.14 @@ -53,9 +49,9 @@
9.15
9.16 ScriptEngine[] arr = { null };
9.17 code = StaticMethodTest.compileClass(sb, arr,
9.18 - "org/apidesign/vm4brwsr/GenJS"
9.19 + "org/apidesign/vm4brwsr/VM"
9.20 );
9.21 - arr[0].getContext().setAttribute("loader", new FindBytes(), ScriptContext.ENGINE_SCOPE);
9.22 + arr[0].getContext().setAttribute("loader", new BytesLoader(), ScriptContext.ENGINE_SCOPE);
9.23 codeSeq = sb;
9.24 }
9.25
9.26 @@ -88,35 +84,4 @@
9.27 }
9.28 assertEquals(ret, expRes, msg + "was: " + ret + "\n" + StaticMethodTest.dumpJS(codeSeq));
9.29 }
9.30 -
9.31 - public static final class FindBytes {
9.32 - private static Set<String> requested = new TreeSet<String>();
9.33 -
9.34 - public byte[] get(String name) throws IOException {
9.35 - if (!requested.add(name)) {
9.36 - throw new IllegalStateException("Requested for second time: " + name);
9.37 - }
9.38 -
9.39 - InputStream is = VMLazyTest.class.getClassLoader().getResourceAsStream(name);
9.40 - if (is == null) {
9.41 - throw new IOException("Can't find " + name);
9.42 - }
9.43 - byte[] arr = new byte[is.available()];
9.44 - int len = is.read(arr);
9.45 - if (len != arr.length) {
9.46 - throw new IOException("Read only " + len + " wanting " + arr.length);
9.47 - }
9.48 - /*
9.49 - System.err.print("loader['" + name + "'] = [");
9.50 - for (int i = 0; i < arr.length; i++) {
9.51 - if (i > 0) {
9.52 - System.err.print(", ");
9.53 - }
9.54 - System.err.print(arr[i]);
9.55 - }
9.56 - System.err.println("]");
9.57 - */
9.58 - return arr;
9.59 - }
9.60 - }
9.61 }