Merging Lubo's closure work into default branch. Release 0.5 will have (partial) support for effective static compilation
1.1 --- a/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/Knockout.java Fri Mar 22 00:05:41 2013 +0100
1.2 +++ b/javaquery/api/src/main/java/org/apidesign/bck2brwsr/htmlpage/Knockout.java Mon Mar 25 13:33:03 2013 +0100
1.3 @@ -70,18 +70,18 @@
1.4
1.5 @JavaScriptBody(args = { "bindings", "model", "prop", "getter", "setter", "primitive" }, body =
1.6 "var bnd = {\n"
1.7 - + " read: function() {\n"
1.8 + + " 'read': function() {\n"
1.9 + " var v = model[getter]();\n"
1.10 + " return v;\n"
1.11 + " },\n"
1.12 - + " owner: bindings\n"
1.13 + + " 'owner': bindings\n"
1.14 + "};\n"
1.15 + "if (setter != null) {\n"
1.16 - + " bnd.write = function(val) {\n"
1.17 + + " bnd['write'] = function(val) {\n"
1.18 + " model[setter](primitive ? new Number(val) : val);\n"
1.19 + " };\n"
1.20 + "}\n"
1.21 - + "bindings[prop] = ko.computed(bnd);"
1.22 + + "bindings[prop] = ko['computed'](bnd);"
1.23 )
1.24 private static void bind(
1.25 Object bindings, Object model, String prop, String getter, String setter, boolean primitive
2.1 --- a/javaquery/demo-calculator-dynamic/pom.xml Fri Mar 22 00:05:41 2013 +0100
2.2 +++ b/javaquery/demo-calculator-dynamic/pom.xml Mon Mar 25 13:33:03 2013 +0100
2.3 @@ -27,7 +27,8 @@
2.4 </execution>
2.5 </executions>
2.6 <configuration>
2.7 - <startpage>org/apidesign/bck2brwsr/demo/calc/Calculator.xhtml</startpage>
2.8 + <directory>${project.build.directory}/${project.build.finalName}-bck2brwsr/public_html</directory>
2.9 + <startpage>index.xhtml</startpage>
2.10 </configuration>
2.11 </plugin>
2.12 <plugin>
3.1 --- a/javaquery/demo-calculator-dynamic/src/main/resources/org/apidesign/bck2brwsr/demo/calc/Calculator.xhtml Fri Mar 22 00:05:41 2013 +0100
3.2 +++ b/javaquery/demo-calculator-dynamic/src/main/resources/org/apidesign/bck2brwsr/demo/calc/Calculator.xhtml Mon Mar 25 13:33:03 2013 +0100
3.3 @@ -80,7 +80,7 @@
3.4
3.5 <script src="bck2brwsr.js"></script>
3.6 <script type="text/javascript">
3.7 - var vm = bck2brwsr('demo.calculator-0.3-SNAPSHOT.jar');
3.8 + var vm = bck2brwsr('demo.calculator-0.5-SNAPSHOT.jar');
3.9 vm.loadClass('org.apidesign.bck2brwsr.demo.calc.Calc');
3.10 </script>
3.11
4.1 --- a/javaquery/demo-calculator/pom.xml Fri Mar 22 00:05:41 2013 +0100
4.2 +++ b/javaquery/demo-calculator/pom.xml Mon Mar 25 13:33:03 2013 +0100
4.3 @@ -31,6 +31,7 @@
4.4 <directory>${project.build.directory}/${project.build.finalName}-bck2brwsr/public_html/</directory>
4.5 <startpage>index.xhtml</startpage>
4.6 <javascript>${project.build.directory}/bck2brwsr.js</javascript>
4.7 + <obfuscation>FULL</obfuscation>
4.8 </configuration>
4.9 </plugin>
4.10 <plugin>
5.1 --- a/rt/emul/mini/src/main/java/java/lang/reflect/Array.java Fri Mar 22 00:05:41 2013 +0100
5.2 +++ b/rt/emul/mini/src/main/java/java/lang/reflect/Array.java Mon Mar 25 13:33:03 2013 +0100
5.3 @@ -636,9 +636,9 @@
5.4 + "arr.jvmName = sig;\n"
5.5 + "return arr;"
5.6 )
5.7 - private static native Object newArray(boolean primitive, String sig, int length);
5.8 + static native Object newArray(boolean primitive, String sig, int length);
5.9
5.10 - private static Object multiNewArray(String sig, int[] dims, int index)
5.11 + static Object multiNewArray(String sig, int[] dims, int index)
5.12 throws IllegalArgumentException, NegativeArraySizeException {
5.13 if (dims.length == index + 1) {
5.14 return newArray(sig.length() == 2, sig, dims[index]);
6.1 --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java Fri Mar 22 00:05:41 2013 +0100
6.2 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java Mon Mar 25 13:33:03 2013 +0100
6.3 @@ -35,6 +35,7 @@
6.4 import org.apache.maven.plugins.annotations.Parameter;
6.5 import org.apache.maven.project.MavenProject;
6.6 import org.apidesign.vm4brwsr.Bck2Brwsr;
6.7 +import org.apidesign.vm4brwsr.ObfuscationLevel;
6.8
6.9 /** Compiles classes into JavaScript. */
6.10 @Mojo(name="j2js", defaultPhase=LifecyclePhase.PROCESS_CLASSES)
6.11 @@ -47,7 +48,7 @@
6.12 /** JavaScript file to generate */
6.13 @Parameter
6.14 private File javascript;
6.15 -
6.16 +
6.17 /** Additional classes that should be pre-compiled into the javascript
6.18 * file. By default compiles all classes found under <code>classes</code>
6.19 * directory and their transitive closure.
6.20 @@ -57,8 +58,14 @@
6.21
6.22 @Parameter(defaultValue="${project}")
6.23 private MavenProject prj;
6.24 -
6.25 -
6.26 +
6.27 + /**
6.28 + * The obfuscation level for the generated JavaScript file.
6.29 + *
6.30 + * @since 0.5
6.31 + */
6.32 + @Parameter(defaultValue="NONE")
6.33 + private ObfuscationLevel obfuscation;
6.34
6.35 @Override
6.36 public void execute() throws MojoExecutionException {
6.37 @@ -81,7 +88,11 @@
6.38 try {
6.39 URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
6.40 FileWriter w = new FileWriter(javascript);
6.41 - Bck2Brwsr.generate(w, url, arr.toArray(new String[0]));
6.42 + Bck2Brwsr.newCompiler().
6.43 + obfuscation(obfuscation).
6.44 + resources(url).
6.45 + addRootClasses(arr.toArray(new String[0])).
6.46 + generate(w);
6.47 w.close();
6.48 } catch (IOException ex) {
6.49 throw new MojoExecutionException("Can't compile", ex);
7.1 --- a/rt/vm/pom.xml Fri Mar 22 00:05:41 2013 +0100
7.2 +++ b/rt/vm/pom.xml Mon Mar 25 13:33:03 2013 +0100
7.3 @@ -83,18 +83,23 @@
7.4 <execution>
7.5 <id>generate-js</id>
7.6 <phase>process-classes</phase>
7.7 + <configuration>
7.8 + <executable>java</executable>
7.9 + <arguments>
7.10 + <argument>-cp</argument>
7.11 + <classpath/>
7.12 + <argument>org.apidesign.vm4brwsr.Main</argument>
7.13 + <argument>--obfuscatelevel</argument>
7.14 + <argument>MINIMAL</argument>
7.15 + <argument>${project.build.directory}/bck2brwsr.js</argument>
7.16 + <argument>org/apidesign/vm4brwsr/Bck2Brwsr</argument>
7.17 + </arguments>
7.18 + </configuration>
7.19 <goals>
7.20 - <goal>java</goal>
7.21 + <goal>exec</goal>
7.22 </goals>
7.23 </execution>
7.24 </executions>
7.25 - <configuration>
7.26 - <mainClass>org.apidesign.vm4brwsr.Main</mainClass>
7.27 - <arguments>
7.28 - <argument>${project.build.directory}/bck2brwsr.js</argument>
7.29 - <argument>org/apidesign/vm4brwsr/Bck2Brwsr</argument>
7.30 - </arguments>
7.31 - </configuration>
7.32 </plugin>
7.33 <plugin>
7.34 <artifactId>maven-assembly-plugin</artifactId>
7.35 @@ -140,5 +145,11 @@
7.36 <version>${project.version}</version>
7.37 <scope>compile</scope>
7.38 </dependency>
7.39 + <dependency>
7.40 + <groupId>com.google.javascript</groupId>
7.41 + <artifactId>closure-compiler</artifactId>
7.42 + <version>r2388</version>
7.43 + <scope>compile</scope>
7.44 + </dependency>
7.45 </dependencies>
7.46 </project>
8.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Fri Mar 22 00:05:41 2013 +0100
8.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java Mon Mar 25 13:33:03 2013 +0100
8.3 @@ -54,46 +54,127 @@
8.4 * @author Jaroslav Tulach <jtulach@netbeans.org>
8.5 */
8.6 public final class Bck2Brwsr {
8.7 - private Bck2Brwsr() {
8.8 + private final ObfuscationLevel level;
8.9 + private final StringArray classes;
8.10 + private final Resources res;
8.11 +
8.12 + private Bck2Brwsr(ObfuscationLevel level, StringArray classes, Resources resources) {
8.13 + this.level = level;
8.14 + this.classes = classes;
8.15 + this.res = resources;
8.16 }
8.17
8.18 - /** Generates virtual machine from bytes served by a <code>resources</code>
8.19 + /** Helper method to generate virtual machine from bytes served by a <code>resources</code>
8.20 * provider.
8.21 - *
8.22 + *
8.23 * @param out the output to write the generated JavaScript to
8.24 * @param resources provider of class files to use
8.25 * @param classes additional classes to include in the generated script
8.26 * @throws IOException I/O exception can be thrown when something goes wrong
8.27 */
8.28 public static void generate(Appendable out, Resources resources, String... classes) throws IOException {
8.29 - StringArray arr = StringArray.asList(classes);
8.30 - arr.add(VM.class.getName().replace('.', '/'));
8.31 - VM.compile(resources, out, arr);
8.32 + newCompiler().resources(resources).addRootClasses(classes).generate(out);
8.33 }
8.34 -
8.35 - /** Generates virtual machine from bytes served by a class loader.
8.36 - *
8.37 +
8.38 + /** Helper method to generate virtual machine from bytes served by a class loader.
8.39 + *
8.40 * @param out the output to write the generated JavaScript to
8.41 * @param loader class loader to load needed classes from
8.42 * @param classes additional classes to include in the generated script
8.43 * @throws IOException I/O exception can be thrown when something goes wrong
8.44 */
8.45 - public static void generate(Appendable out, final ClassLoader loader, String... classes) throws IOException {
8.46 - class R implements Resources {
8.47 - @Override
8.48 - public InputStream get(String name) throws IOException {
8.49 - Enumeration<URL> en = loader.getResources(name);
8.50 - URL u = null;
8.51 - while (en.hasMoreElements()) {
8.52 - u = en.nextElement();
8.53 - }
8.54 - if (u == null) {
8.55 - throw new IOException("Can't find " + name);
8.56 - }
8.57 - return u.openStream();
8.58 + public static void generate(Appendable out, ClassLoader loader, String... classes) throws IOException {
8.59 + newCompiler().resources(loader).addRootClasses(classes).generate(out);
8.60 + }
8.61 +
8.62 + /** Creates new instance of Bck2Brwsr compiler which is ready to generate
8.63 + * empty Bck2Brwsr virtual machine. The instance can be further
8.64 + * configured by calling chain of methods. For example:
8.65 + * <pre>
8.66 + * {@link #createCompiler()}.{@link #resources(org.apidesign.vm4brwsr.Bck2Brwsr.Resources) resources(loader)}.{@link #addRootClasses(java.lang.String[]) addRootClasses("your/Clazz")}.{@link #generate(java.lang.Appendable) generate(out)};
8.67 + * </pre>
8.68 + *
8.69 + * @return new instance of the Bck2Brwsr compiler
8.70 + * @since 0.5
8.71 + */
8.72 + public static Bck2Brwsr newCompiler() {
8.73 + StringArray arr = StringArray.asList(VM.class.getName().replace('.', '/'));
8.74 + return new Bck2Brwsr(ObfuscationLevel.NONE, arr, null);
8.75 + }
8.76 +
8.77 + /** Creates new instance of the Bck2Brwsr compiler which inherits
8.78 + * all values from <code>this</code> instance and adds additional classes
8.79 + * to the list of those that should be compiled by the {@link #generate(java.lang.Appendable)}
8.80 + * method.
8.81 + *
8.82 + * @param classes the classes to add to the compilation
8.83 + * @return new instance of the compiler
8.84 + */
8.85 + public Bck2Brwsr addRootClasses(String... classes) {
8.86 + if (classes.length == 0) {
8.87 + return this;
8.88 + } else {
8.89 + return new Bck2Brwsr(level, this.classes.addAndNew(classes), res);
8.90 + }
8.91 + }
8.92 +
8.93 + /** Changes the obfuscation level for the compiler by creating new instance
8.94 + * which inherits all values from <code>this</code> and adjust the level
8.95 + * of obfuscation.
8.96 + *
8.97 + * @param level the new level of obfuscation
8.98 + * @return new instance of the compiler with changed level of obfuscation
8.99 + * @since 0.5
8.100 + */
8.101 + public Bck2Brwsr obfuscation(ObfuscationLevel level) {
8.102 + return new Bck2Brwsr(level, classes, res);
8.103 + }
8.104 +
8.105 + /** A way to change the provider of additional resources (classes) for the
8.106 + * compiler.
8.107 + *
8.108 + * @param res the implementation of resources provider
8.109 + * @return new instance of the compiler with all values remaining the same, just
8.110 + * with different resources provider
8.111 + * @since 0.5
8.112 + */
8.113 + public Bck2Brwsr resources(Resources res) {
8.114 + return new Bck2Brwsr(level, classes, res);
8.115 + }
8.116 +
8.117 + /** A way to change the provider of additional resources (classes) for the
8.118 + * compiler by specifying classloader to use for loading them.
8.119 + *
8.120 + * @param loader class loader to load the resources from
8.121 + * @return new instance of the compiler with all values being the same, just
8.122 + * different resources provider
8.123 + * @since 0.5
8.124 + */
8.125 + public Bck2Brwsr resources(final ClassLoader loader) {
8.126 + return resources(new LdrRsrcs(loader));
8.127 + }
8.128 +
8.129 + /** Generates virtual machine based on previous configuration of the
8.130 + * compiler.
8.131 + *
8.132 + * @param out the output to write the generated JavaScript to
8.133 + * @since 0.5
8.134 + */
8.135 + public void generate(Appendable out) throws IOException {
8.136 + Resources r = res != null ? res : new LdrRsrcs(Bck2Brwsr.class.getClassLoader());
8.137 + if (level != ObfuscationLevel.NONE) {
8.138 + try {
8.139 + ClosureWrapper.produceTo(out, level, r, classes);
8.140 + return;
8.141 + } catch (IOException ex) {
8.142 + throw ex;
8.143 + } catch (Throwable ex) {
8.144 + out.append("/* Failed to obfuscate: " + ex.getMessage()
8.145 + + " */\n");
8.146 }
8.147 }
8.148 - generate(out, new R(), classes);
8.149 +
8.150 + VM.compile(r, out, classes);
8.151 }
8.152
8.153 /** Provider of resources (classes and other files). The
9.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Fri Mar 22 00:05:41 2013 +0100
9.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Mon Mar 25 13:33:03 2013 +0100
9.3 @@ -28,9 +28,16 @@
9.4 abstract class ByteCodeToJavaScript {
9.5 private ClassData jc;
9.6 final Appendable out;
9.7 + final ObfuscationDelegate obfuscationDelegate;
9.8
9.9 protected ByteCodeToJavaScript(Appendable out) {
9.10 + this(out, ObfuscationDelegate.NULL);
9.11 + }
9.12 +
9.13 + protected ByteCodeToJavaScript(
9.14 + Appendable out, ObfuscationDelegate obfuscationDelegate) {
9.15 this.out = out;
9.16 + this.obfuscationDelegate = obfuscationDelegate;
9.17 }
9.18
9.19 /* Collects additional required resources.
9.20 @@ -58,7 +65,9 @@
9.21 /* protected */ String accessClass(String classOperation) {
9.22 return classOperation;
9.23 }
9.24 -
9.25 +
9.26 + abstract String getVMObject();
9.27 +
9.28 /** Prints out a debug message.
9.29 *
9.30 * @param msg the message
9.31 @@ -92,7 +101,9 @@
9.32 "resource", "processByteCode"
9.33 );
9.34 if (arr != null) {
9.35 - requireScript(arr[0]);
9.36 + if (!arr[0].isEmpty()) {
9.37 + requireScript(arr[0]);
9.38 + }
9.39 if ("0".equals(arr[1])) {
9.40 return null;
9.41 }
9.42 @@ -104,7 +115,8 @@
9.43 StringArray toInitilize = new StringArray();
9.44 final String className = className(jc);
9.45 out.append("\n\n").append(assignClass(className));
9.46 - out.append("function CLS() {");
9.47 + out.append("function ").append(className).append("() {");
9.48 + out.append("\n var CLS = ").append(className).append(';');
9.49 out.append("\n if (!CLS.$class) {");
9.50 if (proto == null) {
9.51 String sc = jc.getSuperClassName(); // with _
9.52 @@ -136,6 +148,8 @@
9.53 append(className).append('_').append(v.getName())
9.54 .append("; };");
9.55 }
9.56 +
9.57 + obfuscationDelegate.exportField(out, "c", "_" + v.getName(), v);
9.58 }
9.59 for (MethodData m : jc.getMethods()) {
9.60 byte[] onlyArr = m.findAnnotationData(true);
9.61 @@ -150,33 +164,39 @@
9.62 }
9.63 continue;
9.64 }
9.65 - String prefix;
9.66 + String destObject;
9.67 String mn;
9.68 + out.append("\n ");
9.69 if (m.isStatic()) {
9.70 - prefix = "\n c.";
9.71 - mn = generateStaticMethod(prefix, m, toInitilize);
9.72 + destObject = "c";
9.73 + mn = generateStaticMethod(destObject, m, toInitilize);
9.74 } else {
9.75 if (m.isConstructor()) {
9.76 - prefix = "\n CLS.";
9.77 - mn = generateInstanceMethod(prefix, m);
9.78 + destObject = "CLS";
9.79 + mn = generateInstanceMethod(destObject, m);
9.80 } else {
9.81 - prefix = "\n c.";
9.82 - mn = generateInstanceMethod(prefix, m);
9.83 + destObject = "c";
9.84 + mn = generateInstanceMethod(destObject, m);
9.85 }
9.86 }
9.87 + obfuscationDelegate.exportMethod(out, destObject, mn, m);
9.88 byte[] runAnno = m.findAnnotationData(false);
9.89 if (runAnno != null) {
9.90 - out.append(prefix).append(mn).append(".anno = {");
9.91 + out.append("\n ").append(destObject).append(".").append(mn).append(".anno = {");
9.92 generateAnno(jc, out, runAnno);
9.93 out.append("\n };");
9.94 }
9.95 - out.append(prefix).append(mn).append(".access = " + m.getAccess()).append(";");
9.96 - out.append(prefix).append(mn).append(".cls = CLS;");
9.97 + out.append("\n ").append(destObject).append(".").append(mn).append(".access = " + m.getAccess()).append(";");
9.98 + out.append("\n ").append(destObject).append(".").append(mn).append(".cls = CLS;");
9.99 }
9.100 out.append("\n c.constructor = CLS;");
9.101 - out.append("\n c.$instOf_").append(className).append(" = true;");
9.102 + String instOfName = "$instOf_" + className;
9.103 + out.append("\n c.").append(instOfName).append(" = true;");
9.104 + obfuscationDelegate.exportJSProperty(out, "c", instOfName);
9.105 for (String superInterface : jc.getSuperInterfaces()) {
9.106 - out.append("\n c.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
9.107 + instOfName = "$instOf_" + superInterface.replace('/', '_');
9.108 + out.append("\n c.").append(instOfName).append(" = true;");
9.109 + obfuscationDelegate.exportJSProperty(out, "c", instOfName);
9.110 }
9.111 out.append("\n CLS.$class = 'temp';");
9.112 out.append("\n CLS.$class = ");
9.113 @@ -222,14 +242,17 @@
9.114 out.append("\n }");
9.115 out.append("\n return arguments[0] ? new CLS() : CLS.prototype;");
9.116 out.append("\n};");
9.117 +
9.118 + obfuscationDelegate.exportClass(out, getVMObject(), className, jc);
9.119 +
9.120 // StringBuilder sb = new StringBuilder();
9.121 // for (String init : toInitilize.toArray()) {
9.122 // sb.append("\n").append(init).append("();");
9.123 // }
9.124 return "";
9.125 }
9.126 - private String generateStaticMethod(String prefix, MethodData m, StringArray toInitilize) throws IOException {
9.127 - String jsb = javaScriptBody(prefix, m, true);
9.128 + private String generateStaticMethod(String destObject, MethodData m, StringArray toInitilize) throws IOException {
9.129 + String jsb = javaScriptBody(destObject, m, true);
9.130 if (jsb != null) {
9.131 return jsb;
9.132 }
9.133 @@ -237,28 +260,28 @@
9.134 if (mn.equals("class__V")) {
9.135 toInitilize.add(accessClass(className(jc)) + "(false)." + mn);
9.136 }
9.137 - generateMethod(prefix, mn, m);
9.138 + generateMethod(destObject, mn, m);
9.139 return mn;
9.140 }
9.141
9.142 - private String generateInstanceMethod(String prefix, MethodData m) throws IOException {
9.143 - String jsb = javaScriptBody(prefix, m, false);
9.144 + private String generateInstanceMethod(String destObject, MethodData m) throws IOException {
9.145 + String jsb = javaScriptBody(destObject, m, false);
9.146 if (jsb != null) {
9.147 return jsb;
9.148 }
9.149 final String mn = findMethodName(m, new StringBuilder());
9.150 - generateMethod(prefix, mn, m);
9.151 + generateMethod(destObject, mn, m);
9.152 return mn;
9.153 }
9.154
9.155 - private void generateMethod(String prefix, String name, MethodData m)
9.156 + private void generateMethod(String destObject, String name, MethodData m)
9.157 throws IOException {
9.158 final StackMapIterator stackMapIterator = m.createStackMapIterator();
9.159 TrapDataIterator trap = m.getTrapDataIterator();
9.160 final LocalsMapper lmapper =
9.161 new LocalsMapper(stackMapIterator.getArguments());
9.162
9.163 - out.append(prefix).append(name).append(" = function(");
9.164 + out.append(destObject).append(".").append(name).append(" = function(");
9.165 lmapper.outputArguments(out, m.isStatic());
9.166 out.append(") {").append("\n");
9.167
9.168 @@ -1546,7 +1569,7 @@
9.169 return s;
9.170 }
9.171
9.172 - private String javaScriptBody(String prefix, MethodData m, boolean isStatic) throws IOException {
9.173 + private String javaScriptBody(String destObject, MethodData m, boolean isStatic) throws IOException {
9.174 byte[] arr = m.findAnnotationData(true);
9.175 if (arr == null) {
9.176 return null;
9.177 @@ -1581,7 +1604,7 @@
9.178 }
9.179 StringBuilder cnt = new StringBuilder();
9.180 final String mn = findMethodName(m, cnt);
9.181 - out.append(prefix).append(mn);
9.182 + out.append(destObject).append(".").append(mn);
9.183 out.append(" = function(");
9.184 String space = "";
9.185 int index = 0;
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ClosureWrapper.java Mon Mar 25 13:33:03 2013 +0100
10.3 @@ -0,0 +1,334 @@
10.4 +/**
10.5 + * Back 2 Browser Bytecode Translator
10.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
10.7 + *
10.8 + * This program is free software: you can redistribute it and/or modify
10.9 + * it under the terms of the GNU General Public License as published by
10.10 + * the Free Software Foundation, version 2 of the License.
10.11 + *
10.12 + * This program is distributed in the hope that it will be useful,
10.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.15 + * GNU General Public License for more details.
10.16 + *
10.17 + * You should have received a copy of the GNU General Public License
10.18 + * along with this program. Look for COPYING file in the top folder.
10.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
10.20 + */
10.21 +package org.apidesign.vm4brwsr;
10.22 +
10.23 +import com.google.javascript.jscomp.CommandLineRunner;
10.24 +import com.google.javascript.jscomp.SourceFile;
10.25 +import java.io.IOException;
10.26 +import java.io.OutputStream;
10.27 +import java.io.PrintStream;
10.28 +import java.util.ArrayList;
10.29 +import java.util.Arrays;
10.30 +import java.util.Collection;
10.31 +import java.util.Collections;
10.32 +import java.util.List;
10.33 +import org.apidesign.bck2brwsr.core.ExtraJavaScript;
10.34 +import org.apidesign.vm4brwsr.ByteCodeParser.ClassData;
10.35 +import org.apidesign.vm4brwsr.ByteCodeParser.FieldData;
10.36 +import org.apidesign.vm4brwsr.ByteCodeParser.MethodData;
10.37 +
10.38 +/**
10.39 + *
10.40 + * @author Jaroslav Tulach <jtulach@netbeans.org>
10.41 + */
10.42 +@ExtraJavaScript(processByteCode = false, resource="")
10.43 +final class ClosureWrapper extends CommandLineRunner {
10.44 + private static final String[] ARGS = { "--compilation_level", "SIMPLE_OPTIMIZATIONS", "--js", "bck2brwsr-raw.js" /*, "--debug", "--formatting", "PRETTY_PRINT" */ };
10.45 +
10.46 + private final ClosuresObfuscationDelegate obfuscationDelegate;
10.47 + private final Bck2Brwsr.Resources res;
10.48 + private final StringArray classes;
10.49 +
10.50 + private String compiledCode;
10.51 + private String externsCode;
10.52 +
10.53 + private ClosureWrapper(Appendable out,
10.54 + String compilationLevel,
10.55 + ClosuresObfuscationDelegate obfuscationDelegate,
10.56 + Bck2Brwsr.Resources res, StringArray classes) {
10.57 + super(
10.58 + generateArguments(compilationLevel),
10.59 + new PrintStream(new APS(out)), System.err
10.60 + );
10.61 + this.obfuscationDelegate = obfuscationDelegate;
10.62 + this.res = res;
10.63 + this.classes = classes;
10.64 + }
10.65 +
10.66 + @Override
10.67 + protected List<SourceFile> createInputs(List<String> files, boolean allowStdIn) throws FlagUsageException, IOException {
10.68 + if (files.size() != 1 || !"bck2brwsr-raw.js".equals(files.get(0))) {
10.69 + throw new IOException("Unexpected files: " + files);
10.70 + }
10.71 + return Collections.nCopies(
10.72 + 1,
10.73 + SourceFile.fromGenerator(
10.74 + "bck2brwsr-raw.js",
10.75 + new SourceFile.Generator() {
10.76 + @Override
10.77 + public String getCode() {
10.78 + return getCompiledCode();
10.79 + }
10.80 + }));
10.81 + }
10.82 +
10.83 +
10.84 + @Override
10.85 + protected List<SourceFile> createExterns()
10.86 + throws FlagUsageException, IOException {
10.87 + final List<SourceFile> externsFiles =
10.88 + new ArrayList<SourceFile>(super.createExterns());
10.89 +
10.90 + externsFiles.add(
10.91 + SourceFile.fromGenerator(
10.92 + "bck2brwsr_externs.js",
10.93 + new SourceFile.Generator() {
10.94 + @Override
10.95 + public String getCode() {
10.96 + return getExternsCode();
10.97 + }
10.98 + }));
10.99 + return externsFiles;
10.100 + }
10.101 +
10.102 + private String getCompiledCode() {
10.103 + if (compiledCode == null) {
10.104 + StringBuilder sb = new StringBuilder();
10.105 + try {
10.106 + VM.compile(res, sb, classes, obfuscationDelegate);
10.107 + compiledCode = sb.toString();
10.108 + } catch (IOException ex) {
10.109 + compiledCode = ex.getMessage();
10.110 + }
10.111 + }
10.112 + return compiledCode;
10.113 + }
10.114 +
10.115 + private String getExternsCode() {
10.116 + if (externsCode == null) {
10.117 + // need compiled code at this point
10.118 + getCompiledCode();
10.119 +
10.120 + final StringBuilder sb = new StringBuilder("function RAW() {};\n");
10.121 + for (final String extern: obfuscationDelegate.getExterns()) {
10.122 + sb.append("RAW.prototype.").append(extern).append(";\n");
10.123 + }
10.124 + externsCode = sb.toString();
10.125 + }
10.126 + return externsCode;
10.127 + }
10.128 +
10.129 + private static final class APS extends OutputStream {
10.130 + private final Appendable out;
10.131 +
10.132 + public APS(Appendable out) {
10.133 + this.out = out;
10.134 + }
10.135 + @Override
10.136 + public void write(int b) throws IOException {
10.137 + out.append((char)b);
10.138 + }
10.139 + }
10.140 +
10.141 + private static String[] generateArguments(String compilationLevel) {
10.142 + String[] finalArgs = ARGS.clone();
10.143 + finalArgs[1] = compilationLevel;
10.144 +
10.145 + return finalArgs;
10.146 + }
10.147 +
10.148 + static int produceTo(Appendable w, ObfuscationLevel obfuscationLevel, Bck2Brwsr.Resources resources, StringArray arr) throws IOException {
10.149 + ClosureWrapper cw = create(w, obfuscationLevel, resources, arr);
10.150 + try {
10.151 + return cw.doRun();
10.152 + } catch (FlagUsageException ex) {
10.153 + throw new IOException(ex);
10.154 + }
10.155 + }
10.156 +
10.157 + private static ClosureWrapper create(Appendable w,
10.158 + ObfuscationLevel obfuscationLevel,
10.159 + Bck2Brwsr.Resources resources,
10.160 + StringArray arr) {
10.161 + switch (obfuscationLevel) {
10.162 + case MINIMAL:
10.163 + return new ClosureWrapper(w, "SIMPLE_OPTIMIZATIONS",
10.164 + new SimpleObfuscationDelegate(),
10.165 + resources, arr);
10.166 +/*
10.167 + case MEDIUM:
10.168 + return new ClosureWrapper(w, "ADVANCED_OPTIMIZATIONS",
10.169 + new MediumObfuscationDelegate(),
10.170 + resources, arr);
10.171 +*/
10.172 + case FULL:
10.173 + return new ClosureWrapper(w, "ADVANCED_OPTIMIZATIONS",
10.174 + new FullObfuscationDelegate(),
10.175 + resources, arr);
10.176 + default:
10.177 + throw new IllegalArgumentException(
10.178 + "Unsupported level: " + obfuscationLevel);
10.179 + }
10.180 + }
10.181 +
10.182 + private static abstract class ClosuresObfuscationDelegate
10.183 + extends ObfuscationDelegate {
10.184 + public abstract Collection<String> getExterns();
10.185 + }
10.186 +
10.187 + private static final class SimpleObfuscationDelegate
10.188 + extends ClosuresObfuscationDelegate {
10.189 + @Override
10.190 + public void exportJSProperty(Appendable out,
10.191 + String destObject,
10.192 + String propertyName) throws IOException {
10.193 + }
10.194 +
10.195 + @Override
10.196 + public void exportClass(Appendable out,
10.197 + String destObject,
10.198 + String mangledName,
10.199 + ClassData classData) throws IOException {
10.200 + }
10.201 +
10.202 + @Override
10.203 + public void exportMethod(Appendable out,
10.204 + String destObject,
10.205 + String mangledName,
10.206 + MethodData methodData) throws IOException {
10.207 + }
10.208 +
10.209 + @Override
10.210 + public void exportField(Appendable out,
10.211 + String destObject,
10.212 + String mangledName,
10.213 + FieldData fieldData) throws IOException {
10.214 + }
10.215 +
10.216 + @Override
10.217 + public Collection<String> getExterns() {
10.218 + return Collections.EMPTY_LIST;
10.219 + }
10.220 + }
10.221 +
10.222 + private static abstract class AdvancedObfuscationDelegate
10.223 + extends ClosuresObfuscationDelegate {
10.224 + private static final String[] INITIAL_EXTERNS = {
10.225 + "bck2brwsr",
10.226 + "$class",
10.227 + "anno",
10.228 + "array",
10.229 + "access",
10.230 + "cls",
10.231 + "vm",
10.232 + "loadClass",
10.233 + "loadBytes",
10.234 + "jvmName",
10.235 + "primitive",
10.236 + "superclass",
10.237 + "cnstr",
10.238 + "add32",
10.239 + "sub32",
10.240 + "mul32",
10.241 + "neg32",
10.242 + "toInt8",
10.243 + "toInt16",
10.244 + "next32",
10.245 + "high32",
10.246 + "toInt32",
10.247 + "toFP",
10.248 + "toLong",
10.249 + "toExactString",
10.250 + "add64",
10.251 + "sub64",
10.252 + "mul64",
10.253 + "and64",
10.254 + "or64",
10.255 + "xor64",
10.256 + "shl64",
10.257 + "shr64",
10.258 + "ushr64",
10.259 + "compare64",
10.260 + "neg64",
10.261 + "div32",
10.262 + "mod32",
10.263 + "div64",
10.264 + "mod64",
10.265 + "at",
10.266 + "getClass__Ljava_lang_Class_2",
10.267 + "clone__Ljava_lang_Object_2"
10.268 + };
10.269 +
10.270 + private final Collection<String> externs;
10.271 +
10.272 + protected AdvancedObfuscationDelegate() {
10.273 + externs = new ArrayList<String>(Arrays.asList(INITIAL_EXTERNS));
10.274 + }
10.275 +
10.276 + @Override
10.277 + public void exportClass(Appendable out,
10.278 + String destObject,
10.279 + String mangledName,
10.280 + ClassData classData) throws IOException {
10.281 + exportJSProperty(out, destObject, mangledName);
10.282 + }
10.283 +
10.284 + @Override
10.285 + public void exportMethod(Appendable out,
10.286 + String destObject,
10.287 + String mangledName,
10.288 + MethodData methodData) throws IOException {
10.289 + if ((methodData.access & ByteCodeParser.ACC_PRIVATE) == 0) {
10.290 + exportJSProperty(out, destObject, mangledName);
10.291 + }
10.292 + }
10.293 +
10.294 + @Override
10.295 + public void exportField(Appendable out,
10.296 + String destObject,
10.297 + String mangledName,
10.298 + FieldData fieldData) throws IOException {
10.299 + if ((fieldData.access & ByteCodeParser.ACC_PRIVATE) == 0) {
10.300 + exportJSProperty(out, destObject, mangledName);
10.301 + }
10.302 + }
10.303 +
10.304 + @Override
10.305 + public Collection<String> getExterns() {
10.306 + return externs;
10.307 + }
10.308 +
10.309 + protected void addExtern(String extern) {
10.310 + externs.add(extern);
10.311 + }
10.312 + }
10.313 +
10.314 + private static final class MediumObfuscationDelegate
10.315 + extends AdvancedObfuscationDelegate {
10.316 + @Override
10.317 + public void exportJSProperty(Appendable out,
10.318 + String destObject,
10.319 + String propertyName) {
10.320 + addExtern(propertyName);
10.321 + }
10.322 + }
10.323 +
10.324 + private static final class FullObfuscationDelegate
10.325 + extends AdvancedObfuscationDelegate {
10.326 + @Override
10.327 + public void exportJSProperty(Appendable out,
10.328 + String destObject,
10.329 + String propertyName) throws IOException {
10.330 + out.append("\n").append(destObject).append("['")
10.331 + .append(propertyName)
10.332 + .append("'] = ")
10.333 + .append(destObject).append(".").append(propertyName)
10.334 + .append(";\n");
10.335 + }
10.336 + }
10.337 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/LdrRsrcs.java Mon Mar 25 13:33:03 2013 +0100
11.3 @@ -0,0 +1,48 @@
11.4 +/**
11.5 + * Back 2 Browser Bytecode Translator
11.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
11.7 + *
11.8 + * This program is free software: you can redistribute it and/or modify
11.9 + * it under the terms of the GNU General Public License as published by
11.10 + * the Free Software Foundation, version 2 of the License.
11.11 + *
11.12 + * This program is distributed in the hope that it will be useful,
11.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.15 + * GNU General Public License for more details.
11.16 + *
11.17 + * You should have received a copy of the GNU General Public License
11.18 + * along with this program. Look for COPYING file in the top folder.
11.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
11.20 + */
11.21 +package org.apidesign.vm4brwsr;
11.22 +
11.23 +import java.io.IOException;
11.24 +import java.io.InputStream;
11.25 +import java.net.URL;
11.26 +import java.util.Enumeration;
11.27 +
11.28 +/** Implementation of Resources that delegates to some class loader.
11.29 + *
11.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
11.31 + */
11.32 +final class LdrRsrcs implements Bck2Brwsr.Resources {
11.33 + private final ClassLoader loader;
11.34 +
11.35 + LdrRsrcs(ClassLoader loader) {
11.36 + this.loader = loader;
11.37 + }
11.38 +
11.39 + @Override
11.40 + public InputStream get(String name) throws IOException {
11.41 + Enumeration<URL> en = loader.getResources(name);
11.42 + URL u = null;
11.43 + while (en.hasMoreElements()) {
11.44 + u = en.nextElement();
11.45 + }
11.46 + if (u == null) {
11.47 + throw new IOException("Can't find " + name);
11.48 + }
11.49 + return u.openStream();
11.50 + }
11.51 +}
12.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java Fri Mar 22 00:05:41 2013 +0100
12.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/Main.java Mon Mar 25 13:33:03 2013 +0100
12.3 @@ -31,20 +31,62 @@
12.4 private Main() {}
12.5
12.6 public static void main(String... args) throws IOException {
12.7 + final String obfuscate = "--obfuscatelevel";
12.8 +
12.9 if (args.length < 2) {
12.10 System.err.println("Bck2Brwsr Translator from Java(tm) to JavaScript, (c) Jaroslav Tulach 2012");
12.11 - System.err.println("Usage: java -cp ... -jar ... <file_to_generate_js_code_to> java/lang/Class org/your/App ...");
12.12 - return;
12.13 + System.err.println("Usage: java -cp ... -jar ... [");
12.14 + System.err.print(obfuscate);
12.15 + System.err.print(" [");
12.16 + boolean first = true;
12.17 + for (ObfuscationLevel l : ObfuscationLevel.values()) {
12.18 + if (!first) {
12.19 + System.err.print('|');
12.20 + }
12.21 + System.err.print(l.name());
12.22 + first = false;
12.23 + }
12.24 +
12.25 + System.err.println("] <file_to_generate_js_code_to> java/lang/Class org/your/App ...");
12.26 + System.exit(9);
12.27 }
12.28
12.29 - Writer w = new BufferedWriter(new FileWriter(args[0]));
12.30 - StringArray classes = StringArray.asList(args);
12.31 - classes.delete(0);
12.32 - try {
12.33 - Bck2Brwsr.generate(w, Main.class.getClassLoader(),
12.34 - classes.toArray());
12.35 - } finally {
12.36 - w.close();
12.37 + ObfuscationLevel obfLevel = ObfuscationLevel.NONE;
12.38 + StringArray classes = new StringArray();
12.39 + String generateTo = null;
12.40 + for (int i = 0; i < args.length; i++) {
12.41 + if (obfuscate.equals(args[i])) { // NOI18N
12.42 + i++;
12.43 + try {
12.44 + obfLevel = ObfuscationLevel.valueOf(args[i]);
12.45 + } catch (Exception e) {
12.46 + System.err.print(obfuscate);
12.47 + System.err.print(" parameter needs to be followed by one of ");
12.48 + boolean first = true;
12.49 + for (ObfuscationLevel l : ObfuscationLevel.values()) {
12.50 + if (!first) {
12.51 + System.err.print(", ");
12.52 + }
12.53 + System.err.print(l.name());
12.54 + first = false;
12.55 + }
12.56 + System.err.println();
12.57 + System.exit(1);
12.58 + }
12.59 + continue;
12.60 + }
12.61 + if (generateTo == null) {
12.62 + generateTo = args[i];
12.63 + } else {
12.64 + classes = classes.addAndNew(args[i]);
12.65 + }
12.66 + }
12.67 + try (Writer w = new BufferedWriter(new FileWriter(generateTo))) {
12.68 + Bck2Brwsr.newCompiler().
12.69 + obfuscation(obfLevel).
12.70 + addRootClasses(classes.toArray()).
12.71 + resources(Main.class.getClassLoader()).
12.72 + generate(w);
12.73 }
12.74 }
12.75 }
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ObfuscationDelegate.java Mon Mar 25 13:33:03 2013 +0100
13.3 @@ -0,0 +1,75 @@
13.4 +/**
13.5 + * Back 2 Browser Bytecode Translator
13.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
13.7 + *
13.8 + * This program is free software: you can redistribute it and/or modify
13.9 + * it under the terms of the GNU General Public License as published by
13.10 + * the Free Software Foundation, version 2 of the License.
13.11 + *
13.12 + * This program is distributed in the hope that it will be useful,
13.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
13.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13.15 + * GNU General Public License for more details.
13.16 + *
13.17 + * You should have received a copy of the GNU General Public License
13.18 + * along with this program. Look for COPYING file in the top folder.
13.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
13.20 + */
13.21 +package org.apidesign.vm4brwsr;
13.22 +
13.23 +import java.io.IOException;
13.24 +import org.apidesign.vm4brwsr.ByteCodeParser.ClassData;
13.25 +import org.apidesign.vm4brwsr.ByteCodeParser.FieldData;
13.26 +import org.apidesign.vm4brwsr.ByteCodeParser.MethodData;
13.27 +
13.28 +abstract class ObfuscationDelegate {
13.29 + static ObfuscationDelegate NULL =
13.30 + new ObfuscationDelegate() {
13.31 + @Override
13.32 + public void exportJSProperty(Appendable out,
13.33 + String destObject,
13.34 + String propertyName)
13.35 + throws IOException {
13.36 + }
13.37 +
13.38 + @Override
13.39 + public void exportClass(Appendable out,
13.40 + String destObject,
13.41 + String mangledName,
13.42 + ClassData classData)
13.43 + throws IOException {
13.44 + }
13.45 +
13.46 + @Override
13.47 + public void exportMethod(Appendable out,
13.48 + String destObject,
13.49 + String mangledName,
13.50 + MethodData methodData)
13.51 + throws IOException {
13.52 + }
13.53 +
13.54 + @Override
13.55 + public void exportField(Appendable out,
13.56 + String destObject,
13.57 + String mangledName,
13.58 + FieldData fieldData)
13.59 + throws IOException {
13.60 + }
13.61 + };
13.62 +
13.63 + public abstract void exportJSProperty(
13.64 + Appendable out, String destObject, String propertyName)
13.65 + throws IOException;
13.66 +
13.67 + public abstract void exportClass(
13.68 + Appendable out, String destObject, String mangledName,
13.69 + ClassData classData) throws IOException;
13.70 +
13.71 + public abstract void exportMethod(
13.72 + Appendable out, String destObject, String mangledName,
13.73 + MethodData methodData) throws IOException;
13.74 +
13.75 + public abstract void exportField(
13.76 + Appendable out, String destObject, String mangledName,
13.77 + FieldData fieldData) throws IOException;
13.78 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ObfuscationLevel.java Mon Mar 25 13:33:03 2013 +0100
14.3 @@ -0,0 +1,41 @@
14.4 +/**
14.5 + * Back 2 Browser Bytecode Translator
14.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
14.7 + *
14.8 + * This program is free software: you can redistribute it and/or modify
14.9 + * it under the terms of the GNU General Public License as published by
14.10 + * the Free Software Foundation, version 2 of the License.
14.11 + *
14.12 + * This program is distributed in the hope that it will be useful,
14.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
14.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14.15 + * GNU General Public License for more details.
14.16 + *
14.17 + * You should have received a copy of the GNU General Public License
14.18 + * along with this program. Look for COPYING file in the top folder.
14.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
14.20 + */
14.21 +package org.apidesign.vm4brwsr;
14.22 +
14.23 +/**
14.24 + * Defines obfuscation level of produced JavaScript files.
14.25 + *
14.26 + * @since 0.5
14.27 + */
14.28 +public enum ObfuscationLevel {
14.29 + /** Generated JavaScript is (sort of) human readable. Useful for debugging.
14.30 + * Dynamic capabilities of the virtual machine work on all classes.
14.31 + */
14.32 + NONE,
14.33 + /** White spaces are removed. Names of external symbols remain unchanged.
14.34 + * Dynamic capabilities of the virtual machine work on all classes.
14.35 + */
14.36 + MINIMAL,
14.37 +// temporarily commented out before merge. not well defined yet:
14.38 +// MEDIUM,
14.39 + /** Aggressive obfuscation of everything. Compact, unreadable "one-liner".
14.40 + * One cannot load classes dynamically. Useful mostly for static compilation
14.41 + * of self contained application.
14.42 + */
14.43 + FULL
14.44 +}
15.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/StringArray.java Fri Mar 22 00:05:41 2013 +0100
15.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/StringArray.java Mon Mar 25 13:33:03 2013 +0100
15.3 @@ -43,6 +43,25 @@
15.4 }
15.5 arr[arr.length - 1] = s;
15.6 }
15.7 +
15.8 + StringArray addAndNew(String... values) {
15.9 + int j;
15.10 + String[] tmp;
15.11 + if (arr == null) {
15.12 + tmp = new String[values.length];
15.13 + j = 0;
15.14 + } else {
15.15 + tmp = new String[arr.length + values.length];
15.16 + for (int i = 0; i < arr.length; i++) {
15.17 + tmp[i] = arr[i];
15.18 + }
15.19 + j = arr.length;
15.20 + }
15.21 + for (int i = 0; i < values.length;) {
15.22 + tmp[j++] = values[i++];
15.23 + }
15.24 + return new StringArray(tmp);
15.25 + }
15.26
15.27 public String[] toArray() {
15.28 return arr == null ? new String[0] : arr;
15.29 @@ -93,5 +112,4 @@
15.30 }
15.31 return -1;
15.32 }
15.33 -
15.34 }
16.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Fri Mar 22 00:05:41 2013 +0100
16.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Mon Mar 25 13:33:03 2013 +0100
16.3 @@ -28,7 +28,11 @@
16.4 public VM(Appendable out) {
16.5 super(out);
16.6 }
16.7 -
16.8 +
16.9 + private VM(Appendable out, ObfuscationDelegate obfuscationDelegate) {
16.10 + super(out, obfuscationDelegate);
16.11 + }
16.12 +
16.13 static {
16.14 // uses VMLazy to load dynamic classes
16.15 boolean assertsOn = false;
16.16 @@ -47,6 +51,12 @@
16.17 static void compile(Bck2Brwsr.Resources l, Appendable out, StringArray names) throws IOException {
16.18 new VM(out).doCompile(l, names);
16.19 }
16.20 +
16.21 + static void compile(Bck2Brwsr.Resources l, Appendable out, StringArray names,
16.22 + ObfuscationDelegate obfuscationDelegate) throws IOException {
16.23 + new VM(out, obfuscationDelegate).doCompile(l, names);
16.24 + }
16.25 +
16.26 protected void doCompile(Bck2Brwsr.Resources l, StringArray names) throws IOException {
16.27 out.append("(function VM(global) {var fillInVMSkeleton = function(vm) {");
16.28 StringArray processed = new StringArray();
16.29 @@ -230,4 +240,9 @@
16.30 String accessClass(String className) {
16.31 return "vm." + className;
16.32 }
16.33 +
16.34 + @Override
16.35 + String getVMObject() {
16.36 + return "vm";
16.37 + }
16.38 }
17.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Fri Mar 22 00:05:41 2013 +0100
17.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java Mon Mar 25 13:33:03 2013 +0100
17.3 @@ -151,5 +151,10 @@
17.4 String accessClass(String classOperation) {
17.5 return "vm." + classOperation;
17.6 }
17.7 +
17.8 + @Override
17.9 + String getVMObject() {
17.10 + return "vm";
17.11 + }
17.12 }
17.13 }
18.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/VMinVM.java Fri Mar 22 00:05:41 2013 +0100
18.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/VMinVM.java Mon Mar 25 13:33:03 2013 +0100
18.3 @@ -43,4 +43,9 @@
18.4 @Override
18.5 protected void requireScript(String resourcePath) {
18.6 }
18.7 +
18.8 + @Override
18.9 + String getVMObject() {
18.10 + return "global";
18.11 + }
18.12 }