1.1 --- a/benchmarks/matrix-multiplication/pom.xml Thu Mar 21 15:45:42 2013 +0100
1.2 +++ b/benchmarks/matrix-multiplication/pom.xml Thu Mar 21 17:00:54 2013 +0100
1.3 @@ -37,6 +37,36 @@
1.4 <skip>true</skip>
1.5 </configuration>
1.6 </plugin>
1.7 + <plugin>
1.8 + <groupId>org.codehaus.mojo</groupId>
1.9 + <artifactId>xml-maven-plugin</artifactId>
1.10 + <version>1.0</version>
1.11 + <executions>
1.12 + <execution>
1.13 + <goals>
1.14 + <goal>transform</goal>
1.15 + </goals>
1.16 + <phase>install</phase>
1.17 + </execution>
1.18 + </executions>
1.19 + <configuration>
1.20 + <transformationSets>
1.21 + <transformationSet>
1.22 + <dir>target/surefire-reports</dir>
1.23 + <outputDir>target/surefire-reports</outputDir>
1.24 + <includes>
1.25 + <include>TEST*.xml</include>
1.26 + </includes>
1.27 + <stylesheet>src/main/select-time.xsl</stylesheet>
1.28 + <fileMappers>
1.29 + <fileMapper implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
1.30 + <targetExtension>.csv</targetExtension>
1.31 + </fileMapper>
1.32 + </fileMappers>
1.33 + </transformationSet>
1.34 + </transformationSets>
1.35 + </configuration>
1.36 + </plugin>
1.37 </plugins>
1.38 </build>
1.39
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/benchmarks/matrix-multiplication/src/main/select-time.xsl Thu Mar 21 17:00:54 2013 +0100
2.3 @@ -0,0 +1,55 @@
2.4 +<?xml version="1.0" encoding="UTF-8"?>
2.5 +<!--
2.6 +
2.7 + Back 2 Browser Bytecode Translator
2.8 + Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.9 +
2.10 + This program is free software: you can redistribute it and/or modify
2.11 + it under the terms of the GNU General Public License as published by
2.12 + the Free Software Foundation, version 2 of the License.
2.13 +
2.14 + This program is distributed in the hope that it will be useful,
2.15 + but WITHOUT ANY WARRANTY; without even the implied warranty of
2.16 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.17 + GNU General Public License for more details.
2.18 +
2.19 + You should have received a copy of the GNU General Public License
2.20 + along with this program. Look for COPYING file in the top folder.
2.21 + If not, see http://opensource.org/licenses/GPL-2.0.
2.22 +
2.23 +-->
2.24 +
2.25 +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
2.26 + <xsl:output method="text"/>
2.27 +
2.28 + <xsl:template match="/">
2.29 + <xsl:apply-templates mode="header" select="testsuite/testcase"/><xsl:text>End
2.30 +</xsl:text>
2.31 + <xsl:apply-templates mode="value" select="testsuite/testcase"/><xsl:text>NaN
2.32 +</xsl:text>
2.33 + </xsl:template>
2.34 +
2.35 +
2.36 + <xsl:template match="testcase" mode="header">
2.37 + <xsl:if test="contains(@name,'tenThousand')">
2.38 + <xsl:if test="not(contains(@name, '[Java]'))">
2.39 + <xsl:if test="not(contains(@name, '[Compare'))">
2.40 + <xsl:value-of select="@name"/>
2.41 + <xsl:text>,</xsl:text>
2.42 + </xsl:if>
2.43 + </xsl:if>
2.44 + </xsl:if>
2.45 + </xsl:template>
2.46 +
2.47 + <xsl:template match="testcase" mode="value">
2.48 + <xsl:if test="contains(@name,'tenThousand')">
2.49 + <xsl:if test="not(contains(@name, '[Java]'))">
2.50 + <xsl:if test="not(contains(@name, '[Compare'))">
2.51 + <xsl:value-of select="@time"/>
2.52 + <xsl:text>,</xsl:text>
2.53 + </xsl:if>
2.54 + </xsl:if>
2.55 + </xsl:if>
2.56 + </xsl:template>
2.57 +
2.58 +</xsl:stylesheet>
3.1 --- a/benchmarks/matrix-multiplication/src/test/java/org/apidesign/benchmark/matrixmul/MatrixTest.java Thu Mar 21 15:45:42 2013 +0100
3.2 +++ b/benchmarks/matrix-multiplication/src/test/java/org/apidesign/benchmark/matrixmul/MatrixTest.java Thu Mar 21 17:00:54 2013 +0100
3.3 @@ -31,6 +31,22 @@
3.4 }
3.5
3.6 @Compare(scripting = false)
3.7 + public String oneIteration() throws IOException {
3.8 +
3.9 + Matrix m1 = new Matrix(5);
3.10 + Matrix m2 = new Matrix(5);
3.11 +
3.12 + m1.generateData();
3.13 + m2.generateData();
3.14 +
3.15 + Matrix res = m1.multiply(m2);
3.16 +
3.17 + StringBuilder sb = new StringBuilder();
3.18 + res.printOn(sb);
3.19 + return sb.toString();
3.20 + }
3.21 +
3.22 + @Compare(scripting = false)
3.23 public String tenThousandIterations() throws IOException {
3.24
3.25 Matrix m1 = new Matrix(5);
3.26 @@ -50,6 +66,27 @@
3.27 return sb.toString();
3.28 }
3.29
3.30 + @Compare(scripting = false)
3.31 + public String tenUselessIterations() throws IOException {
3.32 +
3.33 + Matrix m1 = new Matrix(5);
3.34 + Matrix m2 = new Matrix(5);
3.35 +
3.36 + m1.generateData();
3.37 + m2.generateData();
3.38 +
3.39 + Matrix res = null;
3.40 + for (int i = 0; i < 10; i++) {
3.41 + res = m1.multiply(m2);
3.42 + m1 = res;
3.43 + }
3.44 +
3.45 + StringBuilder sb = new StringBuilder();
3.46 + res.printOn(sb);
3.47 + return sb.toString();
3.48 + }
3.49 +
3.50 +
3.51 @Factory
3.52 public static Object[] create() {
3.53 return VMTest.create(MatrixTest.class);
4.1 --- a/ide/editor/pom.xml Thu Mar 21 15:45:42 2013 +0100
4.2 +++ b/ide/editor/pom.xml Thu Mar 21 17:00:54 2013 +0100
4.3 @@ -16,7 +16,7 @@
4.4
4.5 <properties>
4.6 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
4.7 - <netbeans.version>RELEASE72</netbeans.version>
4.8 + <netbeans.version>RELEASE73</netbeans.version>
4.9 <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
4.10 </properties>
4.11
5.1 --- a/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Thu Mar 21 15:45:42 2013 +0100
5.2 +++ b/javaquery/api/src/test/java/org/apidesign/bck2brwsr/htmlpage/ProcessPageTest.java Thu Mar 21 17:00:54 2013 +0100
5.3 @@ -180,6 +180,9 @@
5.4 }
5.5 Bck2Brwsr.generate(sb, ProcessPageTest.class.getClassLoader(), names);
5.6 sb.append("var vm = this.bck2brwsr();\n");
5.7 + for (String c : names) {
5.8 + sb.append("vm.loadClass('").append(c.replace('/', '.')).append("');\n");
5.9 + }
5.10
5.11 ScriptEngineManager sem = new ScriptEngineManager();
5.12 ScriptEngine js = sem.getEngineByExtension("js");
6.1 --- a/javaquery/demo-calculator-dynamic/nbactions.xml Thu Mar 21 15:45:42 2013 +0100
6.2 +++ b/javaquery/demo-calculator-dynamic/nbactions.xml Thu Mar 21 17:00:54 2013 +0100
6.3 @@ -23,7 +23,7 @@
6.4 <actionName>run</actionName>
6.5 <goals>
6.6 <goal>process-classes</goal>
6.7 - <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
6.8 + <goal>org.apidesign.bck2brwsr:mojo:0.5-SNAPSHOT:brwsr</goal>
6.9 </goals>
6.10 </action>
6.11 </actions>
7.1 --- a/javaquery/demo-calculator-dynamic/src/main/java/org/apidesign/bck2brwsr/demo/calc/Calc.java Thu Mar 21 15:45:42 2013 +0100
7.2 +++ b/javaquery/demo-calculator-dynamic/src/main/java/org/apidesign/bck2brwsr/demo/calc/Calc.java Thu Mar 21 17:00:54 2013 +0100
7.3 @@ -48,18 +48,18 @@
7.4 }
7.5
7.6 @On(event = CLICK, id= { "plus", "minus", "mul", "div" })
7.7 - static void applyOp(Calculator c, String op) {
7.8 + static void applyOp(Calculator c, String id) {
7.9 c.setMemory(c.getDisplay());
7.10 - c.setOperation(op);
7.11 + c.setOperation(id);
7.12 c.setDisplay(0);
7.13 }
7.14
7.15 @On(event = MOUSE_OVER, id= { "result" })
7.16 - static void attemptingIn(Calculator c, String op) {
7.17 + static void attemptingIn(Calculator c) {
7.18 c.setHover(true);
7.19 }
7.20 @On(event = MOUSE_OUT, id= { "result" })
7.21 - static void attemptingOut(Calculator c, String op) {
7.22 + static void attemptingOut(Calculator c) {
7.23 c.setHover(false);
7.24 }
7.25
7.26 @@ -84,18 +84,18 @@
7.27 }
7.28
7.29 @On(event = CLICK, id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"})
7.30 - static void addDigit(String digit, Calculator c) {
7.31 - digit = digit.substring(1);
7.32 + static void addDigit(String id, Calculator c) {
7.33 + id = id.substring(1);
7.34
7.35 double v = c.getDisplay();
7.36 if (v == 0.0) {
7.37 - c.setDisplay(Integer.parseInt(digit));
7.38 + c.setDisplay(Integer.parseInt(id));
7.39 } else {
7.40 String txt = Double.toString(v);
7.41 if (txt.endsWith(".0")) {
7.42 txt = txt.substring(0, txt.length() - 2);
7.43 }
7.44 - txt = txt + digit;
7.45 + txt = txt + id;
7.46 c.setDisplay(Double.parseDouble(txt));
7.47 }
7.48 }
8.1 --- a/javaquery/demo-calculator/nbactions.xml Thu Mar 21 15:45:42 2013 +0100
8.2 +++ b/javaquery/demo-calculator/nbactions.xml Thu Mar 21 17:00:54 2013 +0100
8.3 @@ -23,7 +23,7 @@
8.4 <actionName>run</actionName>
8.5 <goals>
8.6 <goal>package</goal>
8.7 - <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
8.8 + <goal>org.apidesign.bck2brwsr:mojo:0.5-SNAPSHOT:brwsr</goal>
8.9 </goals>
8.10 <properties>
8.11 <skipTests>true</skipTests>
9.1 --- a/javaquery/demo-calculator/pom.xml Thu Mar 21 15:45:42 2013 +0100
9.2 +++ b/javaquery/demo-calculator/pom.xml Thu Mar 21 17:00:54 2013 +0100
9.3 @@ -22,6 +22,7 @@
9.4 <executions>
9.5 <execution>
9.6 <goals>
9.7 + <goal>j2js</goal>
9.8 <goal>brwsr</goal>
9.9 </goals>
9.10 </execution>
9.11 @@ -29,6 +30,7 @@
9.12 <configuration>
9.13 <directory>${project.build.directory}/${project.build.finalName}-bck2brwsr/public_html/</directory>
9.14 <startpage>index.xhtml</startpage>
9.15 + <javascript>${project.build.directory}/bck2brwsr.js</javascript>
9.16 </configuration>
9.17 </plugin>
9.18 <plugin>
9.19 @@ -102,13 +104,5 @@
9.20 <artifactId>javaquery.api</artifactId>
9.21 <version>0.5-SNAPSHOT</version>
9.22 </dependency>
9.23 - <dependency>
9.24 - <groupId>org.apidesign.bck2brwsr</groupId>
9.25 - <artifactId>vm4brwsr</artifactId>
9.26 - <classifier>js</classifier>
9.27 - <type>zip</type>
9.28 - <version>0.5-SNAPSHOT</version>
9.29 - <scope>provided</scope>
9.30 - </dependency>
9.31 </dependencies>
9.32 </project>
10.1 --- a/javaquery/demo-calculator/src/main/assembly/bck2brwsr.xml Thu Mar 21 15:45:42 2013 +0100
10.2 +++ b/javaquery/demo-calculator/src/main/assembly/bck2brwsr.xml Thu Mar 21 17:00:54 2013 +0100
10.3 @@ -37,15 +37,6 @@
10.4 <include>*:rt</include>
10.5 </includes>
10.6 </dependencySet>
10.7 - <dependencySet>
10.8 - <useProjectArtifact>false</useProjectArtifact>
10.9 - <scope>provided</scope>
10.10 - <includes>
10.11 - <include>*:js</include>
10.12 - </includes>
10.13 - <unpack>true</unpack>
10.14 - <outputDirectory>/</outputDirectory>
10.15 - </dependencySet>
10.16 </dependencySets>
10.17 <files>
10.18 <file>
10.19 @@ -53,6 +44,10 @@
10.20 <outputDirectory>/</outputDirectory>
10.21 </file>
10.22 <file>
10.23 + <source>${project.build.directory}/bck2brwsr.js</source>
10.24 + <outputDirectory>/</outputDirectory>
10.25 + </file>
10.26 + <file>
10.27 <source>${project.build.directory}/classes/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml</source>
10.28 <outputDirectory>/</outputDirectory>
10.29 <destName>index.xhtml</destName>
11.1 --- a/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calc.java Thu Mar 21 15:45:42 2013 +0100
11.2 +++ b/javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calc.java Thu Mar 21 17:00:54 2013 +0100
11.3 @@ -48,18 +48,18 @@
11.4 }
11.5
11.6 @On(event = CLICK, id= { "plus", "minus", "mul", "div" })
11.7 - static void applyOp(Calculator c, String op) {
11.8 + static void applyOp(Calculator c, String id) {
11.9 c.setMemory(c.getDisplay());
11.10 - c.setOperation(op);
11.11 + c.setOperation(id);
11.12 c.setDisplay(0);
11.13 }
11.14
11.15 @On(event = MOUSE_OVER, id= { "result" })
11.16 - static void attemptingIn(Calculator c, String op) {
11.17 + static void attemptingIn(Calculator c) {
11.18 c.setHover(true);
11.19 }
11.20 @On(event = MOUSE_OUT, id= { "result" })
11.21 - static void attemptingOut(Calculator c, String op) {
11.22 + static void attemptingOut(Calculator c) {
11.23 c.setHover(false);
11.24 }
11.25
11.26 @@ -84,18 +84,18 @@
11.27 }
11.28
11.29 @On(event = CLICK, id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"})
11.30 - static void addDigit(String digit, Calculator c) {
11.31 - digit = digit.substring(1);
11.32 + static void addDigit(String id, Calculator c) {
11.33 + id = id.substring(1);
11.34
11.35 double v = c.getDisplay();
11.36 if (v == 0.0) {
11.37 - c.setDisplay(Integer.parseInt(digit));
11.38 + c.setDisplay(Integer.parseInt(id));
11.39 } else {
11.40 String txt = Double.toString(v);
11.41 if (txt.endsWith(".0")) {
11.42 txt = txt.substring(0, txt.length() - 2);
11.43 }
11.44 - txt = txt + digit;
11.45 + txt = txt + id;
11.46 c.setDisplay(Double.parseDouble(txt));
11.47 }
11.48 }
12.1 --- a/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Thu Mar 21 15:45:42 2013 +0100
12.2 +++ b/javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/demo/calc/staticcompilation/Calculator.xhtml Thu Mar 21 17:00:54 2013 +0100
12.3 @@ -79,7 +79,7 @@
12.4 <div data-bind="text: displayPreview"></div>
12.5 <script src="bck2brwsr.js"/>
12.6 <script>
12.7 - var vm = bck2brwsr('demo.static.calculator-0.3-SNAPSHOT.jar');
12.8 + var vm = bck2brwsr('demo.static.calculator-0.5-SNAPSHOT.jar');
12.9 vm.loadClass('org.apidesign.bck2brwsr.demo.calc.staticcompilation.Calc');
12.10 </script>
12.11 </body>
13.1 --- a/pom.xml Thu Mar 21 15:45:42 2013 +0100
13.2 +++ b/pom.xml Thu Mar 21 17:00:54 2013 +0100
13.3 @@ -139,13 +139,13 @@
13.4 <dependency>
13.5 <groupId>org.netbeans.api</groupId>
13.6 <artifactId>org-netbeans-modules-classfile</artifactId>
13.7 - <version>RELEASE72</version>
13.8 + <version>RELEASE73</version>
13.9 <type>jar</type>
13.10 </dependency>
13.11 <dependency>
13.12 <groupId>org.netbeans.api</groupId>
13.13 <artifactId>org-openide-util-lookup</artifactId>
13.14 - <version>RELEASE72</version>
13.15 + <version>RELEASE73</version>
13.16 <scope>compile</scope>
13.17 <type>jar</type>
13.18 </dependency>
14.1 --- a/rt/emul/mini/src/main/java/java/lang/AbstractStringBuilder.java Thu Mar 21 15:45:42 2013 +0100
14.2 +++ b/rt/emul/mini/src/main/java/java/lang/AbstractStringBuilder.java Thu Mar 21 17:00:54 2013 +0100
14.3 @@ -126,7 +126,7 @@
14.4 throw new OutOfMemoryError();
14.5 newCapacity = Integer.MAX_VALUE;
14.6 }
14.7 - value = copyOf(value, newCapacity);
14.8 + value = System.expandArray(value, newCapacity);
14.9 }
14.10
14.11 /**
15.1 --- a/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Thu Mar 21 15:45:42 2013 +0100
15.2 +++ b/rt/emul/mini/src/main/java/org/apidesign/bck2brwsr/emul/lang/System.java Thu Mar 21 17:00:54 2013 +0100
15.3 @@ -54,6 +54,11 @@
15.4 )
15.5 public static native byte[] expandArray(byte[] arr, int expectedSize);
15.6
15.7 + @JavaScriptBody(args = { "arr", "expectedSize" }, body =
15.8 + "while (expectedSize-- > arr.length) { arr.push(0); }; return arr;"
15.9 + )
15.10 + public static native char[] expandArray(char[] arr, int expectedSize);
15.11 +
15.12 @JavaScriptBody(args = {}, body = "return new Date().getTime();")
15.13 private static native double currentTimeMillisDouble();
15.14
16.1 --- a/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Thu Mar 21 15:45:42 2013 +0100
16.2 +++ b/rt/emul/mini/src/main/resources/org/apidesign/vm4brwsr/emul/lang/java_lang_Number.js Thu Mar 21 17:00:54 2013 +0100
16.3 @@ -551,3 +551,5 @@
16.4 return negateResult ? result.neg64() : result;
16.5 }
16.6 })(Number.prototype);
16.7 +
16.8 +vm.java_lang_Number(false);
17.1 --- a/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java Thu Mar 21 15:45:42 2013 +0100
17.2 +++ b/rt/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java Thu Mar 21 17:00:54 2013 +0100
17.3 @@ -20,7 +20,6 @@
17.4 import java.io.Closeable;
17.5 import java.io.File;
17.6 import java.io.IOException;
17.7 -import java.net.URLClassLoader;
17.8 import org.apidesign.vm4brwsr.Bck2Brwsr;
17.9
17.10 /** An abstraction for executing tests in a Bck2Brwsr virtual machine.
17.11 @@ -93,7 +92,7 @@
17.12 * @return interface that allows one to stop the server
17.13 * @throws IOException if something goes wrong
17.14 */
17.15 - public static Closeable showURL(URLClassLoader classes, String startpage) throws IOException {
17.16 + public static Closeable showURL(ClassLoader classes, String startpage) throws IOException {
17.17 Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
17.18 l.addClassLoader(classes);
17.19 l.showURL(startpage);
18.1 --- a/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java Thu Mar 21 15:45:42 2013 +0100
18.2 +++ b/rt/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/Java2JavaScript.java Thu Mar 21 17:00:54 2013 +0100
18.3 @@ -44,11 +44,17 @@
18.4 /** Root of the class files */
18.5 @Parameter(defaultValue="${project.build.directory}/classes")
18.6 private File classes;
18.7 - /** File to generate. Defaults bootjava.js in the first non-empty
18.8 - package under the classes directory */
18.9 + /** JavaScript file to generate */
18.10 @Parameter
18.11 private File javascript;
18.12
18.13 + /** Additional classes that should be pre-compiled into the javascript
18.14 + * file. By default compiles all classes found under <code>classes</code>
18.15 + * directory and their transitive closure.
18.16 + */
18.17 + @Parameter
18.18 + private List<String> compileclasses;
18.19 +
18.20 @Parameter(defaultValue="${project}")
18.21 private MavenProject prj;
18.22
18.23 @@ -60,13 +66,14 @@
18.24 throw new MojoExecutionException("Can't find " + classes);
18.25 }
18.26
18.27 - if (javascript == null) {
18.28 - javascript = new File(findNonEmptyFolder(classes), "bootjava.js");
18.29 - }
18.30 -
18.31 List<String> arr = new ArrayList<String>();
18.32 long newest = collectAllClasses("", classes, arr);
18.33
18.34 + if (compileclasses != null) {
18.35 + arr.retainAll(compileclasses);
18.36 + arr.addAll(compileclasses);
18.37 + }
18.38 +
18.39 if (javascript.lastModified() > newest) {
18.40 return;
18.41 }
18.42 @@ -81,17 +88,6 @@
18.43 }
18.44 }
18.45
18.46 - private static File findNonEmptyFolder(File dir) throws MojoExecutionException {
18.47 - if (!dir.isDirectory()) {
18.48 - throw new MojoExecutionException("Not a directory " + dir);
18.49 - }
18.50 - File[] arr = dir.listFiles();
18.51 - if (arr.length == 1 && arr[0].isDirectory()) {
18.52 - return findNonEmptyFolder(arr[0]);
18.53 - }
18.54 - return dir;
18.55 - }
18.56 -
18.57 private static long collectAllClasses(String prefix, File toCheck, List<String> arr) {
18.58 File[] files = toCheck.listFiles();
18.59 if (files != null) {
18.60 @@ -104,7 +100,8 @@
18.61 }
18.62 return newest;
18.63 } else if (toCheck.getName().endsWith(".class")) {
18.64 - arr.add(prefix.substring(0, prefix.length() - 7));
18.65 + final String cls = prefix.substring(0, prefix.length() - 7);
18.66 + arr.add(cls);
18.67 return toCheck.lastModified();
18.68 } else {
18.69 return 0L;
18.70 @@ -115,7 +112,9 @@
18.71 List<URL> arr = new ArrayList<URL>();
18.72 arr.add(root.toURI().toURL());
18.73 for (Artifact a : deps) {
18.74 - arr.add(a.getFile().toURI().toURL());
18.75 + if (a.getFile() != null) {
18.76 + arr.add(a.getFile().toURI().toURL());
18.77 + }
18.78 }
18.79 return new URLClassLoader(arr.toArray(new URL[0]), Java2JavaScript.class.getClassLoader());
18.80 }
19.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Mar 21 15:45:42 2013 +0100
19.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Thu Mar 21 17:00:54 2013 +0100
19.3 @@ -191,6 +191,9 @@
19.4 generateAnno(jc, out, classAnno);
19.5 out.append("\n };");
19.6 }
19.7 + for (String init : toInitilize.toArray()) {
19.8 + out.append("\n ").append(init).append("();");
19.9 + }
19.10 out.append("\n }");
19.11 out.append("\n if (arguments.length === 0) {");
19.12 out.append("\n if (!(this instanceof CLS)) {");
19.13 @@ -219,11 +222,11 @@
19.14 out.append("\n }");
19.15 out.append("\n return arguments[0] ? new CLS() : CLS.prototype;");
19.16 out.append("\n};");
19.17 - StringBuilder sb = new StringBuilder();
19.18 - for (String init : toInitilize.toArray()) {
19.19 - sb.append("\n").append(init).append("();");
19.20 - }
19.21 - return sb.toString();
19.22 +// StringBuilder sb = new StringBuilder();
19.23 +// for (String init : toInitilize.toArray()) {
19.24 +// sb.append("\n").append(init).append("();");
19.25 +// }
19.26 + return "";
19.27 }
19.28 private String generateStaticMethod(String prefix, MethodData m, StringArray toInitilize) throws IOException {
19.29 String jsb = javaScriptBody(prefix, m, true);
19.30 @@ -278,22 +281,36 @@
19.31 TrapData[] previousTrap = null;
19.32 boolean wide = false;
19.33
19.34 - out.append("\n var gt = 0;\n for(;;) switch(gt) {\n");
19.35 + out.append("\n var gt = 0;\n");
19.36 + int openBraces = 0;
19.37 + int topMostLabel = 0;
19.38 for (int i = 0; i < byteCodes.length; i++) {
19.39 int prev = i;
19.40 stackMapIterator.advanceTo(i);
19.41 boolean changeInCatch = trap.advanceTo(i);
19.42 if (changeInCatch || lastStackFrame != stackMapIterator.getFrameIndex()) {
19.43 if (previousTrap != null) {
19.44 - generateCatch(previousTrap);
19.45 + generateCatch(previousTrap, i, topMostLabel);
19.46 previousTrap = null;
19.47 }
19.48 }
19.49 if (lastStackFrame != stackMapIterator.getFrameIndex()) {
19.50 + if (i != 0) {
19.51 + out.append(" }\n");
19.52 + }
19.53 + if (openBraces > 64) {
19.54 + for (int c = 0; c < 64; c++) {
19.55 + out.append("break;}\n");
19.56 + }
19.57 + openBraces = 1;
19.58 + topMostLabel = i;
19.59 + }
19.60 +
19.61 lastStackFrame = stackMapIterator.getFrameIndex();
19.62 lmapper.syncWithFrameLocals(stackMapIterator.getFrameLocals());
19.63 smapper.syncWithFrameStack(stackMapIterator.getFrameStack());
19.64 - out.append(" case " + i).append(": ");
19.65 + out.append(" X_" + i).append(": for (;;) { IF: if (gt <= " + i + ") {\n");
19.66 + openBraces++;
19.67 changeInCatch = true;
19.68 } else {
19.69 debug(" /* " + i + " */ ");
19.70 @@ -765,7 +782,7 @@
19.71 }
19.72 case opc_ldc_w:
19.73 case opc_ldc2_w: {
19.74 - int indx = readIntArg(byteCodes, i);
19.75 + int indx = readUShortArg(byteCodes, i);
19.76 i += 2;
19.77 String v = encodeConstant(indx);
19.78 int type = VarType.fromConstantType(jc.getTag(indx));
19.79 @@ -796,133 +813,104 @@
19.80 break;
19.81 case opc_if_acmpeq:
19.82 i = generateIf(byteCodes, i, smapper.popA(), smapper.popA(),
19.83 - "===");
19.84 + "===", topMostLabel);
19.85 break;
19.86 case opc_if_acmpne:
19.87 i = generateIf(byteCodes, i, smapper.popA(), smapper.popA(),
19.88 - "!==");
19.89 + "!==", topMostLabel);
19.90 break;
19.91 case opc_if_icmpeq:
19.92 i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
19.93 - "==");
19.94 + "==", topMostLabel);
19.95 break;
19.96 case opc_ifeq: {
19.97 - int indx = i + readIntArg(byteCodes, i);
19.98 - emit(out, "if (@1 == 0) { gt = @2; continue; }",
19.99 - smapper.popI(), Integer.toString(indx));
19.100 + int indx = i + readShortArg(byteCodes, i);
19.101 + emitIf(out, "if (@1 == 0) ",
19.102 + smapper.popI(), i, indx, topMostLabel);
19.103 i += 2;
19.104 break;
19.105 }
19.106 case opc_ifne: {
19.107 - int indx = i + readIntArg(byteCodes, i);
19.108 - emit(out, "if (@1 != 0) { gt = @2; continue; }",
19.109 - smapper.popI(), Integer.toString(indx));
19.110 + int indx = i + readShortArg(byteCodes, i);
19.111 + emitIf(out, "if (@1 != 0) ",
19.112 + smapper.popI(), i, indx, topMostLabel);
19.113 i += 2;
19.114 break;
19.115 }
19.116 case opc_iflt: {
19.117 - int indx = i + readIntArg(byteCodes, i);
19.118 - emit(out, "if (@1 < 0) { gt = @2; continue; }",
19.119 - smapper.popI(), Integer.toString(indx));
19.120 + int indx = i + readShortArg(byteCodes, i);
19.121 + emitIf(out, "if (@1 < 0) ",
19.122 + smapper.popI(), i, indx, topMostLabel);
19.123 i += 2;
19.124 break;
19.125 }
19.126 case opc_ifle: {
19.127 - int indx = i + readIntArg(byteCodes, i);
19.128 - emit(out, "if (@1 <= 0) { gt = @2; continue; }",
19.129 - smapper.popI(), Integer.toString(indx));
19.130 + int indx = i + readShortArg(byteCodes, i);
19.131 + emitIf(out, "if (@1 <= 0) ",
19.132 + smapper.popI(), i, indx, topMostLabel);
19.133 i += 2;
19.134 break;
19.135 }
19.136 case opc_ifgt: {
19.137 - int indx = i + readIntArg(byteCodes, i);
19.138 - emit(out, "if (@1 > 0) { gt = @2; continue; }",
19.139 - smapper.popI(), Integer.toString(indx));
19.140 + int indx = i + readShortArg(byteCodes, i);
19.141 + emitIf(out, "if (@1 > 0) ",
19.142 + smapper.popI(), i, indx, topMostLabel);
19.143 i += 2;
19.144 break;
19.145 }
19.146 case opc_ifge: {
19.147 - int indx = i + readIntArg(byteCodes, i);
19.148 - emit(out, "if (@1 >= 0) { gt = @2; continue; }",
19.149 - smapper.popI(), Integer.toString(indx));
19.150 + int indx = i + readShortArg(byteCodes, i);
19.151 + emitIf(out, "if (@1 >= 0) ",
19.152 + smapper.popI(), i, indx, topMostLabel);
19.153 i += 2;
19.154 break;
19.155 }
19.156 case opc_ifnonnull: {
19.157 - int indx = i + readIntArg(byteCodes, i);
19.158 - emit(out, "if (@1 !== null) { gt = @2; continue; }",
19.159 - smapper.popA(), Integer.toString(indx));
19.160 + int indx = i + readShortArg(byteCodes, i);
19.161 + emitIf(out, "if (@1 !== null) ",
19.162 + smapper.popA(), i, indx, topMostLabel);
19.163 i += 2;
19.164 break;
19.165 }
19.166 case opc_ifnull: {
19.167 - int indx = i + readIntArg(byteCodes, i);
19.168 - emit(out, "if (@1 === null) { gt = @2; continue; }",
19.169 - smapper.popA(), Integer.toString(indx));
19.170 + int indx = i + readShortArg(byteCodes, i);
19.171 + emitIf(out, "if (@1 === null) ",
19.172 + smapper.popA(), i, indx, topMostLabel);
19.173 i += 2;
19.174 break;
19.175 }
19.176 case opc_if_icmpne:
19.177 i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
19.178 - "!=");
19.179 + "!=", topMostLabel);
19.180 break;
19.181 case opc_if_icmplt:
19.182 i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
19.183 - "<");
19.184 + "<", topMostLabel);
19.185 break;
19.186 case opc_if_icmple:
19.187 i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
19.188 - "<=");
19.189 + "<=", topMostLabel);
19.190 break;
19.191 case opc_if_icmpgt:
19.192 i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
19.193 - ">");
19.194 + ">", topMostLabel);
19.195 break;
19.196 case opc_if_icmpge:
19.197 i = generateIf(byteCodes, i, smapper.popI(), smapper.popI(),
19.198 - ">=");
19.199 + ">=", topMostLabel);
19.200 break;
19.201 case opc_goto: {
19.202 - int indx = i + readIntArg(byteCodes, i);
19.203 - emit(out, "gt = @1; continue;", Integer.toString(indx));
19.204 + int indx = i + readShortArg(byteCodes, i);
19.205 + goTo(out, i, indx, topMostLabel);
19.206 i += 2;
19.207 break;
19.208 }
19.209 case opc_lookupswitch: {
19.210 - int table = i / 4 * 4 + 4;
19.211 - int dflt = i + readInt4(byteCodes, table);
19.212 - table += 4;
19.213 - int n = readInt4(byteCodes, table);
19.214 - table += 4;
19.215 - out.append("switch (").append(smapper.popI()).append(") {\n");
19.216 - while (n-- > 0) {
19.217 - int cnstnt = readInt4(byteCodes, table);
19.218 - table += 4;
19.219 - int offset = i + readInt4(byteCodes, table);
19.220 - table += 4;
19.221 - out.append(" case " + cnstnt).append(": gt = " + offset).append("; continue;\n");
19.222 - }
19.223 - out.append(" default: gt = " + dflt).append("; continue;\n}");
19.224 - i = table - 1;
19.225 + i = generateLookupSwitch(i, byteCodes, smapper, topMostLabel);
19.226 break;
19.227 }
19.228 case opc_tableswitch: {
19.229 - int table = i / 4 * 4 + 4;
19.230 - int dflt = i + readInt4(byteCodes, table);
19.231 - table += 4;
19.232 - int low = readInt4(byteCodes, table);
19.233 - table += 4;
19.234 - int high = readInt4(byteCodes, table);
19.235 - table += 4;
19.236 - out.append("switch (").append(smapper.popI()).append(") {\n");
19.237 - while (low <= high) {
19.238 - int offset = i + readInt4(byteCodes, table);
19.239 - table += 4;
19.240 - out.append(" case " + low).append(": gt = " + offset).append("; continue;\n");
19.241 - low++;
19.242 - }
19.243 - out.append(" default: gt = " + dflt).append("; continue;\n}");
19.244 - i = table - 1;
19.245 + i = generateTableSwitch(i, byteCodes, smapper, topMostLabel);
19.246 break;
19.247 }
19.248 case opc_invokeinterface: {
19.249 @@ -939,7 +927,7 @@
19.250 i = invokeStaticMethod(byteCodes, i, smapper, true);
19.251 break;
19.252 case opc_new: {
19.253 - int indx = readIntArg(byteCodes, i);
19.254 + int indx = readUShortArg(byteCodes, i);
19.255 String ci = jc.getClassName(indx);
19.256 emit(out, "var @1 = new @2;",
19.257 smapper.pushA(), accessClass(ci.replace('/', '_')));
19.258 @@ -949,50 +937,18 @@
19.259 }
19.260 case opc_newarray:
19.261 int atype = readUByte(byteCodes, ++i);
19.262 - String jvmType;
19.263 - switch (atype) {
19.264 - case 4: jvmType = "[Z"; break;
19.265 - case 5: jvmType = "[C"; break;
19.266 - case 6: jvmType = "[F"; break;
19.267 - case 7: jvmType = "[D"; break;
19.268 - case 8: jvmType = "[B"; break;
19.269 - case 9: jvmType = "[S"; break;
19.270 - case 10: jvmType = "[I"; break;
19.271 - case 11: jvmType = "[J"; break;
19.272 - default: throw new IllegalStateException("Array type: " + atype);
19.273 - }
19.274 - emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(true, '@3', @1);",
19.275 - smapper.popI(), smapper.pushA(), jvmType);
19.276 + generateNewArray(atype, smapper);
19.277 break;
19.278 case opc_anewarray: {
19.279 - int type = readIntArg(byteCodes, i);
19.280 + int type = readUShortArg(byteCodes, i);
19.281 i += 2;
19.282 - String typeName = jc.getClassName(type);
19.283 - if (typeName.startsWith("[")) {
19.284 - typeName = "[" + typeName;
19.285 - } else {
19.286 - typeName = "[L" + typeName + ";";
19.287 - }
19.288 - emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(false, '@3', @1);",
19.289 - smapper.popI(), smapper.pushA(), typeName);
19.290 + generateANewArray(type, smapper);
19.291 break;
19.292 }
19.293 case opc_multianewarray: {
19.294 - int type = readIntArg(byteCodes, i);
19.295 + int type = readUShortArg(byteCodes, i);
19.296 i += 2;
19.297 - String typeName = jc.getClassName(type);
19.298 - int dim = readUByte(byteCodes, ++i);
19.299 - StringBuilder dims = new StringBuilder();
19.300 - dims.append('[');
19.301 - for (int d = 0; d < dim; d++) {
19.302 - if (d != 0) {
19.303 - dims.insert(1, ",");
19.304 - }
19.305 - dims.insert(1, smapper.popI());
19.306 - }
19.307 - dims.append(']');
19.308 - emit(out, "var @2 = Array.prototype.multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II('@3', @1, 0);",
19.309 - dims.toString(), smapper.pushA(), typeName);
19.310 + i = generateMultiANewArray(type, byteCodes, i, smapper);
19.311 break;
19.312 }
19.313 case opc_arraylength:
19.314 @@ -1206,11 +1162,11 @@
19.315 case opc_sipush:
19.316 emit(out, "var @1 = @2;",
19.317 smapper.pushI(),
19.318 - Integer.toString(readIntArg(byteCodes, i)));
19.319 + Integer.toString(readShortArg(byteCodes, i)));
19.320 i += 2;
19.321 break;
19.322 case opc_getfield: {
19.323 - int indx = readIntArg(byteCodes, i);
19.324 + int indx = readUShortArg(byteCodes, i);
19.325 String[] fi = jc.getFieldInfoName(indx);
19.326 final int type = VarType.fromFieldType(fi[2].charAt(0));
19.327 final String mangleClass = mangleSig(fi[0]);
19.328 @@ -1223,7 +1179,7 @@
19.329 break;
19.330 }
19.331 case opc_putfield: {
19.332 - int indx = readIntArg(byteCodes, i);
19.333 + int indx = readUShortArg(byteCodes, i);
19.334 String[] fi = jc.getFieldInfoName(indx);
19.335 final int type = VarType.fromFieldType(fi[2].charAt(0));
19.336 final String mangleClass = mangleSig(fi[0]);
19.337 @@ -1237,7 +1193,7 @@
19.338 break;
19.339 }
19.340 case opc_getstatic: {
19.341 - int indx = readIntArg(byteCodes, i);
19.342 + int indx = readUShortArg(byteCodes, i);
19.343 String[] fi = jc.getFieldInfoName(indx);
19.344 final int type = VarType.fromFieldType(fi[2].charAt(0));
19.345 emit(out, "var @1 = @2(false)._@3();",
19.346 @@ -1248,7 +1204,7 @@
19.347 break;
19.348 }
19.349 case opc_putstatic: {
19.350 - int indx = readIntArg(byteCodes, i);
19.351 + int indx = readUShortArg(byteCodes, i);
19.352 String[] fi = jc.getFieldInfoName(indx);
19.353 final int type = VarType.fromFieldType(fi[2].charAt(0));
19.354 emit(out, "@1(false)._@2(@3);",
19.355 @@ -1259,33 +1215,14 @@
19.356 break;
19.357 }
19.358 case opc_checkcast: {
19.359 - int indx = readIntArg(byteCodes, i);
19.360 - final String type = jc.getClassName(indx);
19.361 - if (!type.startsWith("[")) {
19.362 - emit(out,
19.363 - "if (@1 !== null && !@1.$instOf_@2) throw {};",
19.364 - smapper.getA(0), type.replace('/', '_'));
19.365 - } else {
19.366 - emit(out, "vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@2').cast__Ljava_lang_Object_2Ljava_lang_Object_2(@1);",
19.367 - smapper.getA(0), type
19.368 - );
19.369 - }
19.370 + int indx = readUShortArg(byteCodes, i);
19.371 + generateCheckcast(indx, smapper);
19.372 i += 2;
19.373 break;
19.374 }
19.375 case opc_instanceof: {
19.376 - int indx = readIntArg(byteCodes, i);
19.377 - final String type = jc.getClassName(indx);
19.378 - if (!type.startsWith("[")) {
19.379 - emit(out, "var @2 = @1 != null && @1.$instOf_@3 ? 1 : 0;",
19.380 - smapper.popA(), smapper.pushI(),
19.381 - type.replace('/', '_'));
19.382 - } else {
19.383 - emit(out, "var @2 = vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@3').isInstance__ZLjava_lang_Object_2(@1);",
19.384 - smapper.popA(), smapper.pushI(),
19.385 - type
19.386 - );
19.387 - }
19.388 + int indx = readUShortArg(byteCodes, i);
19.389 + generateInstanceOf(indx, smapper);
19.390 i += 2;
19.391 break;
19.392 }
19.393 @@ -1321,37 +1258,29 @@
19.394 }
19.395 }
19.396 if (debug(" //")) {
19.397 - for (int j = prev; j <= i; j++) {
19.398 - out.append(" ");
19.399 - final int cc = readUByte(byteCodes, j);
19.400 - out.append(Integer.toString(cc));
19.401 - }
19.402 + generateByteCodeComment(prev, i, byteCodes);
19.403 }
19.404 out.append("\n");
19.405 }
19.406 if (previousTrap != null) {
19.407 - generateCatch(previousTrap);
19.408 + generateCatch(previousTrap, byteCodes.length, topMostLabel);
19.409 }
19.410 - out.append(" }\n");
19.411 - out.append("};");
19.412 + out.append("\n }\n");
19.413 + while (openBraces-- > 0) {
19.414 + out.append('}');
19.415 + }
19.416 + out.append("\n};");
19.417 }
19.418
19.419 - private int generateIf(byte[] byteCodes, int i,
19.420 - final Variable v2, final Variable v1,
19.421 - final String test) throws IOException {
19.422 - int indx = i + readIntArg(byteCodes, i);
19.423 + private int generateIf(byte[] byteCodes, int i, final Variable v2, final Variable v1, final String test, int topMostLabel) throws IOException {
19.424 + int indx = i + readShortArg(byteCodes, i);
19.425 out.append("if (").append(v1)
19.426 .append(' ').append(test).append(' ')
19.427 - .append(v2).append(") { gt = " + indx)
19.428 - .append("; continue; }");
19.429 + .append(v2).append(") ");
19.430 + goTo(out, i, indx, topMostLabel);
19.431 return i + 2;
19.432 }
19.433 -
19.434 - private int readIntArg(byte[] byteCodes, int offsetInstruction) {
19.435 - final int indxHi = byteCodes[offsetInstruction + 1] << 8;
19.436 - final int indxLo = byteCodes[offsetInstruction + 2];
19.437 - return (indxHi & 0xffffff00) | (indxLo & 0xff);
19.438 - }
19.439 +
19.440 private int readInt4(byte[] byteCodes, int offset) {
19.441 final int d = byteCodes[offset + 0] << 24;
19.442 final int c = byteCodes[offset + 1] << 16;
19.443 @@ -1359,18 +1288,25 @@
19.444 final int a = byteCodes[offset + 3];
19.445 return (d & 0xff000000) | (c & 0xff0000) | (b & 0xff00) | (a & 0xff);
19.446 }
19.447 - private int readUByte(byte[] byteCodes, int offset) {
19.448 + private static int readUByte(byte[] byteCodes, int offset) {
19.449 return byteCodes[offset] & 0xff;
19.450 }
19.451
19.452 - private int readUShort(byte[] byteCodes, int offset) {
19.453 + private static int readUShort(byte[] byteCodes, int offset) {
19.454 return ((byteCodes[offset] & 0xff) << 8)
19.455 | (byteCodes[offset + 1] & 0xff);
19.456 }
19.457 + private static int readUShortArg(byte[] byteCodes, int offsetInstruction) {
19.458 + return readUShort(byteCodes, offsetInstruction + 1);
19.459 + }
19.460
19.461 - private int readShort(byte[] byteCodes, int offset) {
19.462 - return (byteCodes[offset] << 8)
19.463 - | (byteCodes[offset + 1] & 0xff);
19.464 + private static int readShort(byte[] byteCodes, int offset) {
19.465 + int signed = byteCodes[offset];
19.466 + byte b0 = (byte)signed;
19.467 + return (b0 << 8) | (byteCodes[offset + 1] & 0xff);
19.468 + }
19.469 + private static int readShortArg(byte[] byteCodes, int offsetInstruction) {
19.470 + return readShort(byteCodes, offsetInstruction + 1);
19.471 }
19.472
19.473 private static void countArgs(String descriptor, char[] returnType, StringBuilder sig, StringBuilder cnt) {
19.474 @@ -1498,7 +1434,7 @@
19.475
19.476 private int invokeStaticMethod(byte[] byteCodes, int i, final StackMapper mapper, boolean isStatic)
19.477 throws IOException {
19.478 - int methodIndex = readIntArg(byteCodes, i);
19.479 + int methodIndex = readUShortArg(byteCodes, i);
19.480 String[] mi = jc.getFieldInfoName(methodIndex);
19.481 char[] returnType = { 'V' };
19.482 StringBuilder cnt = new StringBuilder();
19.483 @@ -1543,7 +1479,7 @@
19.484 }
19.485 private int invokeVirtualMethod(byte[] byteCodes, int i, final StackMapper mapper)
19.486 throws IOException {
19.487 - int methodIndex = readIntArg(byteCodes, i);
19.488 + int methodIndex = readUShortArg(byteCodes, i);
19.489 String[] mi = jc.getFieldInfoName(methodIndex);
19.490 char[] returnType = { 'V' };
19.491 StringBuilder cnt = new StringBuilder();
19.492 @@ -1818,7 +1754,7 @@
19.493 out.append(format, processed, length);
19.494 }
19.495
19.496 - private void generateCatch(TrapData[] traps) throws IOException {
19.497 + private void generateCatch(TrapData[] traps, int current, int topMostLabel) throws IOException {
19.498 out.append("} catch (e) {\n");
19.499 int finallyPC = -1;
19.500 for (TrapData e : traps) {
19.501 @@ -1835,10 +1771,11 @@
19.502 out.append(" var stA0 = vm.java_lang_Throwable(true);");
19.503 out.append(" vm.java_lang_Throwable.cons__VLjava_lang_String_2.call(stA0, e.toString());");
19.504 out.append("}");
19.505 - out.append("gt=" + e.handler_pc + "; continue;");
19.506 + goTo(out, current, e.handler_pc, topMostLabel);
19.507 } else {
19.508 out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
19.509 - out.append("gt=" + e.handler_pc + "; var stA0 = e; continue;");
19.510 + out.append("var stA0 = e;");
19.511 + goTo(out, current, e.handler_pc, topMostLabel);
19.512 out.append("}\n");
19.513 }
19.514 } else {
19.515 @@ -1848,8 +1785,152 @@
19.516 if (finallyPC == -1) {
19.517 out.append("throw e;");
19.518 } else {
19.519 - out.append("gt=" + finallyPC + "; var stA0 = e; continue;");
19.520 + out.append("var stA0 = e;");
19.521 + goTo(out, current, finallyPC, topMostLabel);
19.522 }
19.523 out.append("\n}");
19.524 }
19.525 +
19.526 + private static void goTo(Appendable out, int current, int to, int canBack) throws IOException {
19.527 + if (to < current) {
19.528 + if (canBack < to) {
19.529 + out.append("{ gt = 0; continue X_" + to + "; }");
19.530 + } else {
19.531 + out.append("{ gt = " + to + "; continue X_0; }");
19.532 + }
19.533 + } else {
19.534 + out.append("{ gt = " + to + "; break IF; }");
19.535 + }
19.536 + }
19.537 +
19.538 + private static void emitIf(
19.539 + Appendable out, String pattern, Variable param,
19.540 + int current, int to, int canBack
19.541 + ) throws IOException {
19.542 + emit(out, pattern, param);
19.543 + goTo(out, current, to, canBack);
19.544 + }
19.545 +
19.546 + private void generateNewArray(int atype, final StackMapper smapper) throws IOException, IllegalStateException {
19.547 + String jvmType;
19.548 + switch (atype) {
19.549 + case 4: jvmType = "[Z"; break;
19.550 + case 5: jvmType = "[C"; break;
19.551 + case 6: jvmType = "[F"; break;
19.552 + case 7: jvmType = "[D"; break;
19.553 + case 8: jvmType = "[B"; break;
19.554 + case 9: jvmType = "[S"; break;
19.555 + case 10: jvmType = "[I"; break;
19.556 + case 11: jvmType = "[J"; break;
19.557 + default: throw new IllegalStateException("Array type: " + atype);
19.558 + }
19.559 + emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(true, '@3', @1);",
19.560 + smapper.popI(), smapper.pushA(), jvmType);
19.561 + }
19.562 +
19.563 + private void generateANewArray(int type, final StackMapper smapper) throws IOException {
19.564 + String typeName = jc.getClassName(type);
19.565 + if (typeName.startsWith("[")) {
19.566 + typeName = "[" + typeName;
19.567 + } else {
19.568 + typeName = "[L" + typeName + ";";
19.569 + }
19.570 + emit(out, "var @2 = Array.prototype.newArray__Ljava_lang_Object_2ZLjava_lang_String_2I(false, '@3', @1);",
19.571 + smapper.popI(), smapper.pushA(), typeName);
19.572 + }
19.573 +
19.574 + private int generateMultiANewArray(int type, final byte[] byteCodes, int i, final StackMapper smapper) throws IOException {
19.575 + String typeName = jc.getClassName(type);
19.576 + int dim = readUByte(byteCodes, ++i);
19.577 + StringBuilder dims = new StringBuilder();
19.578 + dims.append('[');
19.579 + for (int d = 0; d < dim; d++) {
19.580 + if (d != 0) {
19.581 + dims.insert(1, ",");
19.582 + }
19.583 + dims.insert(1, smapper.popI());
19.584 + }
19.585 + dims.append(']');
19.586 + emit(out, "var @2 = Array.prototype.multiNewArray__Ljava_lang_Object_2Ljava_lang_String_2_3II('@3', @1, 0);",
19.587 + dims.toString(), smapper.pushA(), typeName);
19.588 + return i;
19.589 + }
19.590 +
19.591 + private int generateTableSwitch(int i, final byte[] byteCodes, final StackMapper smapper, int topMostLabel) throws IOException {
19.592 + int table = i / 4 * 4 + 4;
19.593 + int dflt = i + readInt4(byteCodes, table);
19.594 + table += 4;
19.595 + int low = readInt4(byteCodes, table);
19.596 + table += 4;
19.597 + int high = readInt4(byteCodes, table);
19.598 + table += 4;
19.599 + out.append("switch (").append(smapper.popI()).append(") {\n");
19.600 + while (low <= high) {
19.601 + int offset = i + readInt4(byteCodes, table);
19.602 + table += 4;
19.603 + out.append(" case " + low).append(":"); goTo(out, i, offset, topMostLabel); out.append('\n');
19.604 + low++;
19.605 + }
19.606 + out.append(" default: ");
19.607 + goTo(out, i, dflt, topMostLabel);
19.608 + out.append("\n}");
19.609 + i = table - 1;
19.610 + return i;
19.611 + }
19.612 +
19.613 + private int generateLookupSwitch(int i, final byte[] byteCodes, final StackMapper smapper, int topMostLabel) throws IOException {
19.614 + int table = i / 4 * 4 + 4;
19.615 + int dflt = i + readInt4(byteCodes, table);
19.616 + table += 4;
19.617 + int n = readInt4(byteCodes, table);
19.618 + table += 4;
19.619 + out.append("switch (").append(smapper.popI()).append(") {\n");
19.620 + while (n-- > 0) {
19.621 + int cnstnt = readInt4(byteCodes, table);
19.622 + table += 4;
19.623 + int offset = i + readInt4(byteCodes, table);
19.624 + table += 4;
19.625 + out.append(" case " + cnstnt).append(": "); goTo(out, i, offset, topMostLabel); out.append('\n');
19.626 + }
19.627 + out.append(" default: ");
19.628 + goTo(out, i, dflt, topMostLabel);
19.629 + out.append("\n}");
19.630 + i = table - 1;
19.631 + return i;
19.632 + }
19.633 +
19.634 + private void generateInstanceOf(int indx, final StackMapper smapper) throws IOException {
19.635 + final String type = jc.getClassName(indx);
19.636 + if (!type.startsWith("[")) {
19.637 + emit(out, "var @2 = @1 != null && @1.$instOf_@3 ? 1 : 0;",
19.638 + smapper.popA(), smapper.pushI(),
19.639 + type.replace('/', '_'));
19.640 + } else {
19.641 + emit(out, "var @2 = vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@3').isInstance__ZLjava_lang_Object_2(@1);",
19.642 + smapper.popA(), smapper.pushI(),
19.643 + type
19.644 + );
19.645 + }
19.646 + }
19.647 +
19.648 + private void generateCheckcast(int indx, final StackMapper smapper) throws IOException {
19.649 + final String type = jc.getClassName(indx);
19.650 + if (!type.startsWith("[")) {
19.651 + emit(out,
19.652 + "if (@1 !== null && !@1.$instOf_@2) throw {};",
19.653 + smapper.getA(0), type.replace('/', '_'));
19.654 + } else {
19.655 + emit(out, "vm.java_lang_Class(false).forName__Ljava_lang_Class_2Ljava_lang_String_2('@2').cast__Ljava_lang_Object_2Ljava_lang_Object_2(@1);",
19.656 + smapper.getA(0), type
19.657 + );
19.658 + }
19.659 + }
19.660 +
19.661 + private void generateByteCodeComment(int prev, int i, final byte[] byteCodes) throws IOException {
19.662 + for (int j = prev; j <= i; j++) {
19.663 + out.append(" ");
19.664 + final int cc = readUByte(byteCodes, j);
19.665 + out.append(Integer.toString(cc));
19.666 + }
19.667 + }
19.668 }
20.1 --- a/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Thu Mar 21 15:45:42 2013 +0100
20.2 +++ b/rt/vm/src/main/java/org/apidesign/vm4brwsr/VM.java Thu Mar 21 17:00:54 2013 +0100
20.3 @@ -110,7 +110,10 @@
20.4 for (String ic : toInit.toArray()) {
20.5 int indx = processed.indexOf(ic);
20.6 if (indx >= 0) {
20.7 - out.append(initCode.toArray()[indx]).append("\n");
20.8 + final String theCode = initCode.toArray()[indx];
20.9 + if (!theCode.isEmpty()) {
20.10 + out.append(theCode).append("\n");
20.11 + }
20.12 initCode.toArray()[indx] = "";
20.13 }
20.14 }
21.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Thu Mar 21 15:45:42 2013 +0100
21.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/TestVM.java Thu Mar 21 17:00:54 2013 +0100
21.3 @@ -115,7 +115,7 @@
21.4 if (sb.length() > 2000) {
21.5 sb = dumpJS(sb);
21.6 }
21.7 - fail("Could not evaluate:\n" + sb, ex);
21.8 + fail("Could not evaluate:" + ex.getClass() + ":" + ex.getMessage() + "\n" + sb, ex);
21.9 return null;
21.10 }
21.11 }
22.1 --- a/rt/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java Thu Mar 21 15:45:42 2013 +0100
22.2 +++ b/rt/vm/src/test/java/org/apidesign/vm4brwsr/VMinVMTest.java Thu Mar 21 17:00:54 2013 +0100
22.3 @@ -40,6 +40,14 @@
22.4 compareCode("org/apidesign/vm4brwsr/Classes.class");
22.5 }
22.6
22.7 + @Test public void compareGeneratedCodeForToolkitClass() throws Exception {
22.8 + String genCode = compareCode("org/apidesign/vm4brwsr/Bck2BrwsrToolkit.class");
22.9 + int indx = genCode.indexOf("gt = 65604");
22.10 + if (indx >= 0) {
22.11 + fail("Goto to an invalid label:\n...." + genCode.substring(indx - 30, indx + 30) + "....");
22.12 + }
22.13 + }
22.14 +
22.15 @BeforeClass
22.16 public static void compileTheCode() throws Exception {
22.17 code = TestVM.compileClass("org/apidesign/vm4brwsr/VMinVM");
22.18 @@ -49,7 +57,7 @@
22.19 code = null;
22.20 }
22.21
22.22 - private void compareCode(final String nm) throws Exception, IOException {
22.23 + private String compareCode(final String nm) throws Exception, IOException {
22.24 byte[] arr = BytesLoader.readClass(nm);
22.25 String ret1 = VMinVM.toJavaScript(arr);
22.26
22.27 @@ -88,5 +96,7 @@
22.28 msg.append(code.toString());
22.29 fail(msg.toString());
22.30 }
22.31 +
22.32 + return ret1;
22.33 }
22.34 }
23.1 Binary file rt/vm/src/test/resources/org/apidesign/vm4brwsr/Bck2BrwsrToolkit.class has changed
24.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java Thu Mar 21 15:45:42 2013 +0100
24.2 +++ b/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ByteArithmeticTest.java Thu Mar 21 17:00:54 2013 +0100
24.3 @@ -17,6 +17,7 @@
24.4 */
24.5 package org.apidesign.bck2brwsr.tck;
24.6
24.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
24.8 import org.apidesign.bck2brwsr.vmtest.Compare;
24.9 import org.apidesign.bck2brwsr.vmtest.VMTest;
24.10 import org.testng.annotations.Factory;
24.11 @@ -94,6 +95,50 @@
24.12 @Compare public byte divisionReminder() {
24.13 return mod((byte)1, (byte)2);
24.14 }
24.15 +
24.16 + private static int readShort(byte[] byteCodes, int offset) {
24.17 + int signed = byteCodes[offset];
24.18 + byte b0 = (byte)signed;
24.19 + return (b0 << 8) | (byteCodes[offset + 1] & 0xff);
24.20 + }
24.21 +
24.22 + private static int readShortArg(byte[] byteCodes, int offsetInstruction) {
24.23 + return readShort(byteCodes, offsetInstruction + 1);
24.24 + }
24.25 +
24.26 + @Compare public int readIntArgs255and156() {
24.27 + final byte[] arr = new byte[] { (byte)0, (byte)255, (byte)156 };
24.28 +
24.29 + assert arr[1] == -1 : "First byte: " + arr[1];
24.30 + assert arr[2] == -100 : "Second byte: " + arr[2];
24.31 + final int ret = readShortArg(arr, 0);
24.32 + assert ret < 65000: "Value: " + ret;
24.33 + return ret;
24.34 + }
24.35 +
24.36 + @JavaScriptBody(args = { "arr" }, body = "arr[1] = 255; arr[2] = 156; return arr;")
24.37 + private static byte[] fill255and156(byte[] arr) {
24.38 + arr[1] = (byte)255;
24.39 + arr[2] = (byte)156;
24.40 + return arr;
24.41 + }
24.42 +
24.43 + @Compare public int readIntArgs255and156JSArray() {
24.44 + final byte[] arr = fill255and156(new byte[] { 0, 0, 0 });
24.45 +
24.46 + final int ret = readShortArg(arr, 0);
24.47 + assert ret < 65000: "Value: " + ret;
24.48 + return ret;
24.49 + }
24.50 +
24.51 + @Compare public int readIntArgsMinus1andMinus100() {
24.52 + final byte[] arr = new byte[] { (byte)0, (byte)-1, (byte)-100 };
24.53 +
24.54 + assert arr[1] == -1 : "First byte: " + arr[1];
24.55 + assert arr[2] == -100 : "Second byte: " + arr[2];
24.56 +
24.57 + return readShortArg(arr, 0);
24.58 + }
24.59
24.60 @Factory
24.61 public static Object[] create() {
25.1 --- a/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUse.java Thu Mar 21 15:45:42 2013 +0100
25.2 +++ b/rt/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUse.java Thu Mar 21 17:00:54 2013 +0100
25.3 @@ -19,6 +19,13 @@
25.4
25.5 class StaticUse {
25.6 public static final Object NON_NULL = new Object();
25.7 + public static int cnt;
25.8 + static {
25.9 + if (cnt++ != 0) {
25.10 + throw new IllegalStateException("Multiple initialization of a <cinit>");
25.11 + }
25.12 + }
25.13 +
25.14 StaticUse() {
25.15 }
25.16