1.1 --- a/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java Sun Apr 27 08:33:38 2014 +0200
1.2 +++ b/rt/emul/compact/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java Sun Apr 27 22:40:17 2014 +0200
1.3 @@ -30,6 +30,7 @@
1.4
1.5 @Compare public String readResourceAsStream() throws Exception {
1.6 InputStream is = getClass().getResourceAsStream("Resources.txt");
1.7 + assert is != null : "The stream for Resources.txt should be found";
1.8 byte[] b = new byte[30];
1.9 int len = is.read(b);
1.10 StringBuilder sb = new StringBuilder();
2.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Sun Apr 27 08:33:38 2014 +0200
2.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Sun Apr 27 22:40:17 2014 +0200
2.3 @@ -19,7 +19,6 @@
2.4
2.5 import java.io.IOException;
2.6 import java.io.InputStream;
2.7 -import java.net.URL;
2.8 import org.apidesign.bck2brwsr.core.Exported;
2.9
2.10 /** Build your own virtual machine! Use methods in this class to generate
2.11 @@ -57,14 +56,16 @@
2.12 private final ObfuscationLevel level;
2.13 private final StringArray rootcls;
2.14 private final StringArray classes;
2.15 + private final StringArray resources;
2.16 private final Resources res;
2.17 private final boolean extension;
2.18
2.19 - private Bck2Brwsr(ObfuscationLevel level, StringArray rootcls, StringArray classes, Resources resources, boolean extension) {
2.20 + private Bck2Brwsr(ObfuscationLevel level, StringArray rootcls, StringArray classes, StringArray resources, Resources res, boolean extension) {
2.21 this.level = level;
2.22 this.rootcls = rootcls;
2.23 this.classes = classes;
2.24 - this.res = resources;
2.25 + this.resources = resources;
2.26 + this.res = res;
2.27 this.extension = extension;
2.28 }
2.29
2.30 @@ -102,7 +103,7 @@
2.31 * @since 0.5
2.32 */
2.33 public static Bck2Brwsr newCompiler() {
2.34 - return new Bck2Brwsr(ObfuscationLevel.NONE, new StringArray(), new StringArray(), null, false);
2.35 + return new Bck2Brwsr(ObfuscationLevel.NONE, new StringArray(), new StringArray(), new StringArray(), null, false);
2.36 }
2.37
2.38 /** Adds additional classes
2.39 @@ -122,7 +123,7 @@
2.40 if (classes.length == 0) {
2.41 return this;
2.42 } else {
2.43 - return new Bck2Brwsr(level, rootcls.addAndNew(classes), this.classes, res,
2.44 + return new Bck2Brwsr(level, rootcls.addAndNew(classes), this.classes, resources, res,
2.45 extension);
2.46 }
2.47 }
2.48 @@ -142,11 +143,32 @@
2.49 if (classes.length == 0) {
2.50 return this;
2.51 } else {
2.52 - return new Bck2Brwsr(level, rootcls, this.classes.addAndNew(classes), res,
2.53 + return new Bck2Brwsr(level, rootcls, this.classes.addAndNew(classes), resources, res,
2.54 extension);
2.55 }
2.56 }
2.57
2.58 + /** These resources should be made available in the compiled file in
2.59 + * binary form. These resources can then be loaded
2.60 + * by {@link ClassLoader#getResource(java.lang.String)} and similar
2.61 + * methods.
2.62 + *
2.63 + * @param resources names of the resources to be loaded by {@link Resources#get(java.lang.String)}
2.64 + * @return new instance of the Bck2Brwsr compiler which inherits
2.65 + * all values from <code>this</code> just adds few more resource names
2.66 + * for processing
2.67 + * @since 0.9
2.68 + */
2.69 + public Bck2Brwsr addResources(String... resources) {
2.70 + if (resources.length == 0) {
2.71 + return this;
2.72 + } else {
2.73 + return new Bck2Brwsr(level, rootcls, this.classes,
2.74 + this.resources.addAndNew(resources), res, extension
2.75 + );
2.76 + }
2.77 + }
2.78 +
2.79 /** Changes the obfuscation level for the compiler by creating new instance
2.80 * which inherits all values from <code>this</code> and adjust the level
2.81 * of obfuscation.
2.82 @@ -156,7 +178,7 @@
2.83 * @since 0.5
2.84 */
2.85 public Bck2Brwsr obfuscation(ObfuscationLevel level) {
2.86 - return new Bck2Brwsr(level, rootcls, classes, res, extension);
2.87 + return new Bck2Brwsr(level, rootcls, classes, resources, res, extension);
2.88 }
2.89
2.90 /** A way to change the provider of additional resources (classes) for the
2.91 @@ -168,7 +190,7 @@
2.92 * @since 0.5
2.93 */
2.94 public Bck2Brwsr resources(Resources res) {
2.95 - return new Bck2Brwsr(level, rootcls, classes, res, extension);
2.96 + return new Bck2Brwsr(level, rootcls, classes, resources, res, extension);
2.97 }
2.98
2.99 /** Should one generate a library? By default the system generates
2.100 @@ -183,7 +205,7 @@
2.101 * @since 0.9
2.102 */
2.103 public Bck2Brwsr library(boolean library) {
2.104 - return new Bck2Brwsr(level, rootcls, classes, res, library);
2.105 + return new Bck2Brwsr(level, rootcls, classes, resources, res, library);
2.106 }
2.107
2.108 /** A way to change the provider of additional resources (classes) for the
2.109 @@ -205,10 +227,9 @@
2.110 * @since 0.5
2.111 */
2.112 public void generate(Appendable out) throws IOException {
2.113 - Resources r = res != null ? res : new LdrRsrcs(Bck2Brwsr.class.getClassLoader());
2.114 if (level != ObfuscationLevel.NONE) {
2.115 try {
2.116 - ClosureWrapper.produceTo(out, level, r, rootcls, classes, extension);
2.117 + ClosureWrapper.produceTo(out, level, this);
2.118 return;
2.119 } catch (IOException ex) {
2.120 throw ex;
2.121 @@ -218,7 +239,27 @@
2.122 }
2.123 }
2.124
2.125 - VM.compile(out, r, rootcls, classes, extension);
2.126 + VM.compile(out, this);
2.127 + }
2.128 +
2.129 + //
2.130 + // Internal getters
2.131 + //
2.132 +
2.133 + Resources getResources() {
2.134 + return res != null ? res : new LdrRsrcs(Bck2Brwsr.class.getClassLoader());
2.135 + }
2.136 +
2.137 + String[] allClasses() {
2.138 + return classes.addAndNew(rootcls.toArray()).toArray();
2.139 + }
2.140 +
2.141 + StringArray rootClasses() {
2.142 + return rootcls;
2.143 + }
2.144 +
2.145 + boolean isExtension() {
2.146 + return extension;
2.147 }
2.148
2.149 /** Provider of resources (classes and other files). The
3.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java Sun Apr 27 08:33:38 2014 +0200
3.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java Sun Apr 27 22:40:17 2014 +0200
3.3 @@ -35,28 +35,18 @@
3.4 final class ClosureWrapper extends CommandLineRunner {
3.5 private static final String[] ARGS = { "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--js", "bck2brwsr-raw.js" /*, "--debug", "--formatting", "PRETTY_PRINT" */ };
3.6
3.7 - private final Bck2Brwsr.Resources res;
3.8 - private final StringArray classes;
3.9 - private final boolean extension;
3.10 - private final StringArray rootClasses;
3.11 + private final Bck2Brwsr config;
3.12
3.13 private String compiledCode;
3.14 private String externsCode;
3.15
3.16 - private ClosureWrapper(Appendable out,
3.17 - String compilationLevel,
3.18 - Bck2Brwsr.Resources res,
3.19 - StringArray rootClasses,
3.20 - StringArray classes,
3.21 - boolean extension) {
3.22 + private ClosureWrapper(Appendable out,
3.23 + String compilationLevel, Bck2Brwsr config) {
3.24 super(
3.25 generateArguments(compilationLevel),
3.26 new PrintStream(new APS(out)), System.err
3.27 );
3.28 - this.res = res;
3.29 - this.rootClasses = rootClasses;
3.30 - this.classes = classes;
3.31 - this.extension = extension;
3.32 + this.config = config;
3.33 }
3.34
3.35 @Override
3.36 @@ -99,7 +89,7 @@
3.37 if (compiledCode == null) {
3.38 StringBuilder sb = new StringBuilder();
3.39 try {
3.40 - VM.compile(sb, res, rootClasses, classes, extension);
3.41 + VM.compile(sb, config);
3.42 compiledCode = sb.toString();
3.43 } catch (IOException ex) {
3.44 compiledCode = ex.getMessage();
3.45 @@ -142,17 +132,15 @@
3.46 }
3.47
3.48 static int produceTo(Appendable output,
3.49 - ObfuscationLevel obfuscationLevel,
3.50 - Bck2Brwsr.Resources resources,
3.51 - StringArray rootArr,
3.52 - StringArray arr,
3.53 - boolean extension) throws IOException {
3.54 + ObfuscationLevel obfuscationLevel,
3.55 + Bck2Brwsr config
3.56 + ) throws IOException {
3.57 final ClosureWrapper cw =
3.58 new ClosureWrapper(output,
3.59 (obfuscationLevel == ObfuscationLevel.FULL)
3.60 ? "ADVANCED_OPTIMIZATIONS"
3.61 : "SIMPLE_OPTIMIZATIONS",
3.62 - resources, rootArr, arr, extension);
3.63 + config);
3.64 try {
3.65 return cw.doRun();
3.66 } catch (FlagUsageException ex) {
4.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Sun Apr 27 08:33:38 2014 +0200
4.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Sun Apr 27 22:40:17 2014 +0200
4.3 @@ -64,15 +64,14 @@
4.4 }
4.5
4.6 static void compile(Appendable out,
4.7 - Bck2Brwsr.Resources l,
4.8 - StringArray rootNames,
4.9 - StringArray names,
4.10 - boolean extension
4.11 + Bck2Brwsr config
4.12 ) throws IOException {
4.13 - StringArray both = names.addAndNew(rootNames.toArray());
4.14 + String[] both = config.allClasses();
4.15
4.16 - VM vm = extension ? new Extension(out, l, both.toArray(), rootNames)
4.17 - : new Standalone(out, l, rootNames);
4.18 + VM vm = config.isExtension() ?
4.19 + new Extension(out, config.getResources(), both, config.rootClasses())
4.20 + :
4.21 + new Standalone(out, config.getResources(), config.rootClasses());
4.22
4.23 final StringArray fixedNames = new StringArray();
4.24
4.25 @@ -80,7 +79,7 @@
4.26 fixedNames.add(fixedClass.getName().replace('.', '/'));
4.27 }
4.28
4.29 - vm.doCompile(fixedNames.addAndNew(both.toArray()));
4.30 + vm.doCompile(fixedNames.addAndNew(both));
4.31 }
4.32
4.33 private void doCompile(StringArray names) throws IOException {
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/Resources.java Sun Apr 27 22:40:17 2014 +0200
5.3 @@ -0,0 +1,40 @@
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 +/**
5.27 + *
5.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
5.29 + */
5.30 +public class Resources {
5.31 + public static String loadKO() throws IOException {
5.32 + InputStream is = Resources.class.getResourceAsStream("ko.js");
5.33 + if (is == null) {
5.34 + return "No resource found!";
5.35 + }
5.36 + byte[] arr = new byte[4092];
5.37 + int len = is.read(arr);
5.38 + if (len == -1) {
5.39 + return "No data read!";
5.40 + }
5.41 + return new String(arr, 0, len, "UTF-8");
5.42 + }
5.43 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/ResourcesTest.java Sun Apr 27 22:40:17 2014 +0200
6.3 @@ -0,0 +1,57 @@
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 static org.testng.Assert.*;
6.24 +import org.testng.annotations.AfterClass;
6.25 +import org.testng.annotations.BeforeClass;
6.26 +import org.testng.annotations.Test;
6.27 +
6.28 +/** Tests related to loading resources from the VM.
6.29 + *
6.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
6.31 + */
6.32 +public class ResourcesTest {
6.33 + @Test public void checkNullCast() throws Exception {
6.34 + String exp = Resources.loadKO();
6.35 +
6.36 + assertExec("Loading a precompiled resource:",
6.37 + Resources.class, "loadKO__Ljava_lang_String_2",
6.38 + exp
6.39 + );
6.40 + }
6.41 +
6.42 + private static TestVM code;
6.43 +
6.44 + @BeforeClass
6.45 + public static void compileTheCode() throws Exception {
6.46 + StringBuilder sb = new StringBuilder();
6.47 + code = TestVM.compileClassAndResources(sb, null, "org/apidesign/vm4brwsr/Resources", "org/apidesign/vm4brwsr/ko.js");
6.48 + }
6.49 + @AfterClass
6.50 + public static void releaseTheCode() {
6.51 + code = null;
6.52 + }
6.53 +
6.54 + private void assertExec(
6.55 + String msg, Class<?> clazz, String method,
6.56 + Object ret, Object... args
6.57 + ) throws Exception {
6.58 + code.assertExec(msg, clazz, method, ret, args);
6.59 + }
6.60 +}
7.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Sun Apr 27 08:33:38 2014 +0200
7.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Sun Apr 27 22:40:17 2014 +0200
7.3 @@ -152,6 +152,34 @@
7.4 return null;
7.5 }
7.6 }
7.7 +
7.8 + static TestVM compileClassAndResources(StringBuilder sb, ScriptEngine[] eng, String name, String... resources) throws ScriptException, IOException {
7.9 + if (sb == null) {
7.10 + sb = new StringBuilder();
7.11 + }
7.12 + Bck2Brwsr b2b = Bck2Brwsr.newCompiler().
7.13 + resources(new EmulationResources()).
7.14 + addRootClasses(name).
7.15 + addResources(resources).
7.16 + library(false);
7.17 + b2b.generate(sb);
7.18 + ScriptEngineManager sem = new ScriptEngineManager();
7.19 + ScriptEngine js = sem.getEngineByExtension("js");
7.20 + if (eng != null) {
7.21 + eng[0] = js;
7.22 + }
7.23 + try {
7.24 + Object res = js.eval(sb.toString());
7.25 + assertTrue(js instanceof Invocable, "It is invocable object: " + res);
7.26 + return new TestVM((Invocable) js, sb);
7.27 + } catch (Exception ex) {
7.28 + if (sb.length() > 2000) {
7.29 + sb = dumpJS(sb);
7.30 + }
7.31 + fail("Could not evaluate:" + ex.getClass() + ":" + ex.getMessage() + "\n" + sb, ex);
7.32 + return null;
7.33 + }
7.34 + }
7.35
7.36 Object loadClass(String loadClass, String name) throws ScriptException, NoSuchMethodException {
7.37 return code.invokeMethod(bck2brwsr, "loadClass", Exceptions.class.getName());