Bringing in the most recent advances on the default branch
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 21 Mar 2013 17:00:54 +0100
changeset 867b3768be30aa0
parent 866 9b4751828ceb
parent 865 03fe918c4684
child 868 cd1feff88ca5
child 871 6168fb585ab4
Bringing in the most recent advances on the default branch
     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