merge with trunk arithmetic
authorMartin Soch <Martin.Soch@oracle.com>
Fri, 11 Jan 2013 16:36:28 +0100
brancharithmetic
changeset 42712e866a32b40
parent 426 b5c5d51ddc4b
parent 425 af1d8e828955
child 429 7c4442271367
child 438 7df624c2a0a1
merge with trunk
benchmarks/matrix-multiplication/jsTestDriver.conf
benchmarks/matrix-multiplication/nbactions.xml
benchmarks/matrix-multiplication/src/main/java/org/apidesign/benchmark/matrixmul/Main.java
benchmarks/matrix-multiplication/src/main/resources/org/apidesign/benchmark/matrixmul/multiplication-test.js
benchmarks/run-firefox.sh
emul/src/main/java/java/lang/String.java
javaquery/demo-calculator/nbactions.xml
javaquery/demo-calculator/pom.xml
javaquery/demo-calculator/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java
javaquery/demo-calculator/src/main/resources/org/apidesign/bck2brwsr/mavenhtml/Calculator.xhtml
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
vm/src/test/java/org/apidesign/vm4brwsr/Compare.java
vm/src/test/java/org/apidesign/vm4brwsr/CompareVMs.java
vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareHashTest.java
vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareStringsTest.java
vm/src/test/java/org/apidesign/vm4brwsr/tck/IntegerArithmeticTest.java
vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java
vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java
     1.1 --- a/benchmarks/matrix-multiplication/jsTestDriver.conf	Fri Jan 11 16:07:55 2013 +0100
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,5 +0,0 @@
     1.4 -server: http://localhost:9876
     1.5 -
     1.6 -load:
     1.7 -  - target/classes/org/apidesign/benchmark/matrixmul/*.js
     1.8 -
     2.1 --- a/benchmarks/matrix-multiplication/nbactions.xml	Fri Jan 11 16:07:55 2013 +0100
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,29 +0,0 @@
     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 -<actions>
    2.25 -    <action>
    2.26 -        <actionName>run</actionName>
    2.27 -        <goals>
    2.28 -            <goal>process-classes</goal>
    2.29 -            <goal>org.codehaus.mojo:exec-maven-plugin:1.2.1:exec</goal>
    2.30 -        </goals>
    2.31 -    </action>
    2.32 -</actions>
     3.1 --- a/benchmarks/matrix-multiplication/pom.xml	Fri Jan 11 16:07:55 2013 +0100
     3.2 +++ b/benchmarks/matrix-multiplication/pom.xml	Fri Jan 11 16:36:28 2013 +0100
     3.3 @@ -25,62 +25,9 @@
     3.4                 <target>1.7</target>
     3.5              </configuration>
     3.6            </plugin>
     3.7 -          
     3.8 -          <plugin>
     3.9 -              <groupId>org.apidesign.bck2brwsr</groupId>
    3.10 -              <artifactId>mojo</artifactId>
    3.11 -              <version>0.3-SNAPSHOT</version>
    3.12 -              <executions>
    3.13 -                  <execution>
    3.14 -                      <goals>
    3.15 -                          <goal>j2js</goal>
    3.16 -                      </goals>
    3.17 -                  </execution>
    3.18 -              </executions>
    3.19 -          </plugin>
    3.20 -          
    3.21        </plugins>
    3.22    </build>
    3.23    
    3.24 -  <profiles>
    3.25 -    <profile>
    3.26 -      <id>run-benchmarks</id>
    3.27 -      <activation>
    3.28 -        <property><name>bck2brwsr.runBenchmarks.browsers</name></property>
    3.29 -      </activation>
    3.30 -
    3.31 -      <build>
    3.32 -        <plugins>
    3.33 -
    3.34 -          <plugin>
    3.35 -            <groupId>com.googlecode.jstd-maven-plugin</groupId>
    3.36 -            <artifactId>jstd-maven-plugin</artifactId>
    3.37 -            <version>1.3.2.5</version>
    3.38 -            <configuration>
    3.39 -                <port>9876</port>
    3.40 -                <browser>${bck2brwsr.runBenchmarks.browsers}</browser>
    3.41 -                <browserTimeout>720</browserTimeout>
    3.42 -                <tests>all</tests>
    3.43 -                <config>jsTestDriver.conf</config>
    3.44 -                <reset>true</reset>
    3.45 -                <testOutput>${basedir}/target/testOutput</testOutput>
    3.46 -                <!-- runnerMode>DEBUG</runnerMode -->
    3.47 -            </configuration>
    3.48 -            <executions>
    3.49 -                <execution>
    3.50 -                    <id>run-tests</id>
    3.51 -                    <goals>
    3.52 -                        <goal>test</goal>
    3.53 -                    </goals>
    3.54 -                </execution>
    3.55 -            </executions>
    3.56 -          </plugin>
    3.57 -
    3.58 -        </plugins>
    3.59 -      </build>
    3.60 -    </profile>
    3.61 -  </profiles>
    3.62 -
    3.63    <dependencies>
    3.64      <dependency>
    3.65        <groupId>org.apidesign.bck2brwsr</groupId>
    3.66 @@ -88,24 +35,22 @@
    3.67        <version>0.3-SNAPSHOT</version>
    3.68      </dependency>
    3.69      <dependency>
    3.70 -        <groupId>com.googlecode.jstd-maven-plugin</groupId>
    3.71 -        <artifactId>jstd-maven-plugin</artifactId>
    3.72 -        <version>1.3.2.5</version>
    3.73 -        <scope>test</scope>
    3.74 +      <groupId>org.testng</groupId>
    3.75 +      <artifactId>testng</artifactId>
    3.76 +      <version>6.5.2</version>
    3.77 +      <scope>test</scope>
    3.78 +      <exclusions>
    3.79 +        <exclusion>
    3.80 +          <artifactId>junit</artifactId>
    3.81 +          <groupId>junit</groupId>
    3.82 +        </exclusion>
    3.83 +      </exclusions>
    3.84 +    </dependency>
    3.85 +    <dependency>
    3.86 +      <groupId>org.apidesign.bck2brwsr</groupId>
    3.87 +      <artifactId>vmtest</artifactId>
    3.88 +      <version>0.3-SNAPSHOT</version>
    3.89 +      <scope>test</scope>
    3.90      </dependency>
    3.91    </dependencies>
    3.92 -  
    3.93 -  <repositories>
    3.94 -        <repository>
    3.95 -            <id>jstd-maven-plugin google code repo</id>
    3.96 -            <url>http://jstd-maven-plugin.googlecode.com/svn/maven2</url>
    3.97 -        </repository>
    3.98 -  </repositories>
    3.99 -  <pluginRepositories>
   3.100 -        <pluginRepository>
   3.101 -            <id>jstd-maven-plugin google code repo</id>
   3.102 -            <url>http://jstd-maven-plugin.googlecode.com/svn/maven2</url>
   3.103 -        </pluginRepository>
   3.104 -  </pluginRepositories>
   3.105 -  
   3.106  </project>
     4.1 --- a/benchmarks/matrix-multiplication/src/main/java/org/apidesign/benchmark/matrixmul/Main.java	Fri Jan 11 16:07:55 2013 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,42 +0,0 @@
     4.4 -/**
     4.5 - * Back 2 Browser Bytecode Translator
     4.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     4.7 - *
     4.8 - * This program is free software: you can redistribute it and/or modify
     4.9 - * it under the terms of the GNU General Public License as published by
    4.10 - * the Free Software Foundation, version 2 of the License.
    4.11 - *
    4.12 - * This program is distributed in the hope that it will be useful,
    4.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.15 - * GNU General Public License for more details.
    4.16 - *
    4.17 - * You should have received a copy of the GNU General Public License
    4.18 - * along with this program. Look for COPYING file in the top folder.
    4.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
    4.20 - */
    4.21 -package org.apidesign.benchmark.matrixmul;
    4.22 -
    4.23 -public class Main {
    4.24 -
    4.25 -    public static final int ITERATION_COUNT = 100000;
    4.26 -    
    4.27 -    public static void main(String[] args) {
    4.28 -        Matrix m1 = new Matrix(5);
    4.29 -        Matrix m2 = new Matrix(5);
    4.30 -        
    4.31 -        m1.generateData();
    4.32 -        m2.generateData();
    4.33 -        
    4.34 -        //m1.printOn(System.out);
    4.35 -        //System.out.println("x");
    4.36 -        //m2.printOn(System.out);
    4.37 -        
    4.38 -        for (int i = 0; i < ITERATION_COUNT; i++) {
    4.39 -            m1.multiply(m2);
    4.40 -        }
    4.41 -        
    4.42 -        //System.out.println("=");
    4.43 -        //m1.printOn(System.out);
    4.44 -    }
    4.45 -}
     5.1 --- a/benchmarks/matrix-multiplication/src/main/java/org/apidesign/benchmark/matrixmul/Matrix.java	Fri Jan 11 16:07:55 2013 +0100
     5.2 +++ b/benchmarks/matrix-multiplication/src/main/java/org/apidesign/benchmark/matrixmul/Matrix.java	Fri Jan 11 16:36:28 2013 +0100
     5.3 @@ -17,17 +17,20 @@
     5.4   */
     5.5  package org.apidesign.benchmark.matrixmul;
     5.6  
     5.7 -//import java.io.PrintStream;
     5.8 -//import java.util.Random;
     5.9 +import java.io.IOException;
    5.10 +import java.util.Arrays;
    5.11  
    5.12  public class Matrix {
    5.13 -
    5.14      private final int rank;
    5.15 -    private float data[][];
    5.16 +    private final float data[][];
    5.17      
    5.18      public Matrix(int r) {
    5.19 -        rank = r;
    5.20 -        data = new float[r][r];
    5.21 +        this(r, new float[r][r]);
    5.22 +    }
    5.23 +    
    5.24 +    private Matrix(int r, float[][] data) {
    5.25 +        this.rank = r;
    5.26 +        this.data = data;
    5.27      }
    5.28      
    5.29      public void setElement(int i, int j, float value) {
    5.30 @@ -62,20 +65,44 @@
    5.31                  res[i][j] = ij;
    5.32              }
    5.33          }
    5.34 -        data = res;
    5.35 -        
    5.36 -        return this;
    5.37 +        return new Matrix(rank, res);
    5.38      }
    5.39      
    5.40 -    /*
    5.41 -    public void printOn(PrintStream s) {
    5.42 +    public void printOn(Appendable s) throws IOException {
    5.43          for (int i = 0; i < rank; i++) {
    5.44 +            String sep = "";
    5.45              for (int j = 0; j < rank; j++) {
    5.46 -                s.printf("%f ", data[i][j]);
    5.47 +                s.append(sep + data[i][j]);
    5.48 +                sep = " ";
    5.49              }
    5.50 -            s.println();
    5.51 +            s.append("\n");
    5.52          }
    5.53      }
    5.54 -    */
    5.55 -    
    5.56 +
    5.57 +    @Override
    5.58 +    public boolean equals(Object obj) {
    5.59 +        if (obj instanceof Matrix) {
    5.60 +            Matrix snd = (Matrix)obj;
    5.61 +            if (snd.rank != rank) {
    5.62 +                return false;
    5.63 +            }
    5.64 +            for (int i = 0; i < rank; i++) {
    5.65 +                for (int j = 0; j < rank; j++) {
    5.66 +                    if (data[i][j] != snd.data[i][j]) {
    5.67 +                        return false;
    5.68 +                    }
    5.69 +                }
    5.70 +            }
    5.71 +            return true;
    5.72 +        }
    5.73 +        return false;
    5.74 +    }
    5.75 +
    5.76 +    @Override
    5.77 +    public int hashCode() {
    5.78 +        int hash = 3;
    5.79 +        hash = 97 * hash + this.rank;
    5.80 +        hash = 97 * hash + Arrays.deepHashCode(this.data);
    5.81 +        return hash;
    5.82 +    }
    5.83  }
     6.1 --- a/benchmarks/matrix-multiplication/src/main/resources/org/apidesign/benchmark/matrixmul/multiplication-test.js	Fri Jan 11 16:07:55 2013 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,25 +0,0 @@
     6.4 -/*
     6.5 - * Back 2 Browser Bytecode Translator
     6.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     6.7 - *
     6.8 - * This program is free software: you can redistribute it and/or modify
     6.9 - * it under the terms of the GNU General Public License as published by
    6.10 - * the Free Software Foundation, version 2 of the License.
    6.11 - *
    6.12 - * This program is distributed in the hope that it will be useful,
    6.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.15 - * GNU General Public License for more details.
    6.16 - *
    6.17 - * You should have received a copy of the GNU General Public License
    6.18 - * along with this program. Look for COPYING file in the top folder.
    6.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
    6.20 - */
    6.21 -MatrixTest = TestCase("MatrixTest");
    6.22 -
    6.23 -
    6.24 -MatrixTest.prototype.testMultiplication = function() {
    6.25 -  var vm = new bck2brwsr();
    6.26 -  var x = vm.loadClass("org.apidesign.benchmark.matrixmul.Main");
    6.27 -  x.main__V_3Ljava_lang_String_2(null);
    6.28 -};
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/benchmarks/matrix-multiplication/src/test/java/org/apidesign/benchmark/matrixmul/MatrixTest.java	Fri Jan 11 16:36:28 2013 +0100
     7.3 @@ -0,0 +1,61 @@
     7.4 +/**
     7.5 + * Back 2 Browser Bytecode Translator
     7.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     7.7 + *
     7.8 + * This program is free software: you can redistribute it and/or modify
     7.9 + * it under the terms of the GNU General Public License as published by
    7.10 + * the Free Software Foundation, version 2 of the License.
    7.11 + *
    7.12 + * This program is distributed in the hope that it will be useful,
    7.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.15 + * GNU General Public License for more details.
    7.16 + *
    7.17 + * You should have received a copy of the GNU General Public License
    7.18 + * along with this program. Look for COPYING file in the top folder.
    7.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
    7.20 + */
    7.21 +package org.apidesign.benchmark.matrixmul;
    7.22 +
    7.23 +import java.io.IOException;
    7.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
    7.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
    7.26 +import org.testng.annotations.Factory;
    7.27 +
    7.28 +/**
    7.29 + *
    7.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    7.31 + */
    7.32 +public class MatrixTest {
    7.33 +    public static final int ITERATION_COUNT = 10;
    7.34 +    
    7.35 +    public MatrixTest() {
    7.36 +    }
    7.37 +
    7.38 +    @Compare public String tenThousandIterations() throws IOException {
    7.39 +    
    7.40 +        Matrix m1 = new Matrix(5);
    7.41 +        Matrix m2 = new Matrix(5);
    7.42 +        
    7.43 +        m1.generateData();
    7.44 +        m2.generateData();
    7.45 +        
    7.46 +        Matrix res = null;
    7.47 +        for (int i = 0; i < ITERATION_COUNT; i++) {
    7.48 +            Matrix m = m1.multiply(m2);
    7.49 +            if (res != null && !res.equals(m)) {
    7.50 +                return "different";
    7.51 +            }
    7.52 +            res = m;
    7.53 +        }
    7.54 +        
    7.55 +        StringBuilder sb = new StringBuilder();
    7.56 +        res.printOn(sb);
    7.57 +        return sb.toString();
    7.58 +    }
    7.59 +    
    7.60 +    @Factory
    7.61 +    public static Object[] create() {
    7.62 +        return VMTest.create(MatrixTest.class);
    7.63 +    }
    7.64 +}
     8.1 --- a/benchmarks/run-firefox.sh	Fri Jan 11 16:07:55 2013 +0100
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,20 +0,0 @@
     8.4 -#!/bin/bash
     8.5 -#
     8.6 -# Back 2 Browser Bytecode Translator
     8.7 -# Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     8.8 -#
     8.9 -# This program is free software: you can redistribute it and/or modify
    8.10 -# it under the terms of the GNU General Public License as published by
    8.11 -# the Free Software Foundation, version 2 of the License.
    8.12 -#
    8.13 -# This program is distributed in the hope that it will be useful,
    8.14 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.16 -# GNU General Public License for more details.
    8.17 -#
    8.18 -# You should have received a copy of the GNU General Public License
    8.19 -# along with this program. Look for COPYING file in the top folder.
    8.20 -# If not, see http://opensource.org/licenses/GPL-2.0.
    8.21 -#
    8.22 -
    8.23 -/usr/bin/firefox --display=`echo $DISPLAY` "$@"
     9.1 --- a/emul/src/main/java/java/lang/AbstractStringBuilder.java	Fri Jan 11 16:07:55 2013 +0100
     9.2 +++ b/emul/src/main/java/java/lang/AbstractStringBuilder.java	Fri Jan 11 16:36:28 2013 +0100
     9.3 @@ -1271,8 +1271,7 @@
     9.4       *            <code>null</code>.
     9.5       */
     9.6      public int indexOf(String str, int fromIndex) {
     9.7 -        return String.indexOf(value, 0, count,
     9.8 -                              str.toCharArray(), 0, str.length(), fromIndex);
     9.9 +        return toString().indexOf(str, fromIndex);
    9.10      }
    9.11  
    9.12      /**
    10.1 --- a/emul/src/main/java/java/lang/Class.java	Fri Jan 11 16:07:55 2013 +0100
    10.2 +++ b/emul/src/main/java/java/lang/Class.java	Fri Jan 11 16:36:28 2013 +0100
    10.3 @@ -25,6 +25,7 @@
    10.4  
    10.5  package java.lang;
    10.6  
    10.7 +import java.io.ByteArrayInputStream;
    10.8  import org.apidesign.bck2brwsr.emul.AnnotationImpl;
    10.9  import java.io.InputStream;
   10.10  import java.lang.annotation.Annotation;
   10.11 @@ -32,6 +33,7 @@
   10.12  import java.lang.reflect.Method;
   10.13  import java.lang.reflect.TypeVariable;
   10.14  import org.apidesign.bck2brwsr.core.JavaScriptBody;
   10.15 +import org.apidesign.bck2brwsr.emul.MethodImpl;
   10.16  
   10.17  /**
   10.18   * Instances of the class {@code Class} represent classes and
   10.19 @@ -146,7 +148,7 @@
   10.20                  throws ClassNotFoundException {
   10.21          Class<?> c = loadCls(className, className.replace('.', '_'));
   10.22          if (c == null) {
   10.23 -            throw new ClassNotFoundException();
   10.24 +            throw new ClassNotFoundException(className);
   10.25          }
   10.26          return c;
   10.27      }
   10.28 @@ -209,15 +211,32 @@
   10.29       *             </ul>
   10.30       *
   10.31       */
   10.32 -    @JavaScriptBody(args = "self", body =
   10.33 -          "var inst = self.cnstr();"
   10.34 -        + "inst.cons__V(inst);"
   10.35 -        + "return inst;"
   10.36 +    @JavaScriptBody(args = { "self", "illegal" }, body =
   10.37 +          "\nvar c = self.cnstr;"
   10.38 +        + "\nif (c['cons__V']) {"
   10.39 +        + "\n  if ((c.cons__V.access & 0x1) != 0) {"
   10.40 +        + "\n    var inst = c();"
   10.41 +        + "\n    c.cons__V(inst);"
   10.42 +        + "\n    return inst;"
   10.43 +        + "\n  }"
   10.44 +        + "\n  return illegal;"
   10.45 +        + "\n}"
   10.46 +        + "\nreturn null;"
   10.47      )
   10.48 +    private static native Object newInstance0(Class<?> self, Object illegal);
   10.49 +    
   10.50      public T newInstance()
   10.51          throws InstantiationException, IllegalAccessException
   10.52      {
   10.53 -        throw new UnsupportedOperationException();
   10.54 +        Object illegal = new Object();
   10.55 +        Object inst = newInstance0(this, illegal);
   10.56 +        if (inst == null) {
   10.57 +            throw new InstantiationException(getName());
   10.58 +        }
   10.59 +        if (inst == illegal) {
   10.60 +            throw new IllegalAccessException();
   10.61 +        }
   10.62 +        return (T)inst;
   10.63      }
   10.64  
   10.65      /**
   10.66 @@ -287,7 +306,12 @@
   10.67       * @return  {@code true} if this object represents an interface;
   10.68       *          {@code false} otherwise.
   10.69       */
   10.70 -    public native boolean isInterface();
   10.71 +    public boolean isInterface() {
   10.72 +        return (getAccess() & 0x200) != 0;
   10.73 +    }
   10.74 +    
   10.75 +    @JavaScriptBody(args = "self", body = "return self.access;")
   10.76 +    private native int getAccess();
   10.77  
   10.78  
   10.79      /**
   10.80 @@ -330,6 +354,10 @@
   10.81       * @see     java.lang.Void#TYPE
   10.82       * @since JDK1.1
   10.83       */
   10.84 +    @JavaScriptBody(args = "self", body = 
   10.85 +           "if (self.primitive) return true;"
   10.86 +        + "else return false;"
   10.87 +    )
   10.88      public native boolean isPrimitive();
   10.89  
   10.90      /**
   10.91 @@ -631,7 +659,7 @@
   10.92       * @since JDK1.1
   10.93       */
   10.94      public Method[] getMethods() throws SecurityException {
   10.95 -        return Method.findMethods(this);
   10.96 +        return MethodImpl.findMethods(this, 0x01);
   10.97      }
   10.98  
   10.99      /**
  10.100 @@ -761,10 +789,18 @@
  10.101       * @since JDK1.1
  10.102       */
  10.103      public Method getMethod(String name, Class<?>... parameterTypes)
  10.104 -        throws SecurityException {
  10.105 -        Method m = Method.findMethod(this, name, parameterTypes);
  10.106 +        throws SecurityException, NoSuchMethodException {
  10.107 +        Method m = MethodImpl.findMethod(this, name, parameterTypes);
  10.108          if (m == null) {
  10.109 -            throw new SecurityException(); // XXX: NoSuchMethodException
  10.110 +            StringBuilder sb = new StringBuilder();
  10.111 +            sb.append(getName()).append('.').append(name).append('(');
  10.112 +            String sep = "";
  10.113 +            for (int i = 0; i < parameterTypes.length; i++) {
  10.114 +                sb.append(sep).append(parameterTypes[i].getName());
  10.115 +                sep = ", ";
  10.116 +            }
  10.117 +            sb.append(')');
  10.118 +            throw new NoSuchMethodException(sb.toString());
  10.119          }
  10.120          return m;
  10.121      }
  10.122 @@ -846,13 +882,14 @@
  10.123       */
  10.124       public InputStream getResourceAsStream(String name) {
  10.125          name = resolveName(name);
  10.126 -        ClassLoader cl = getClassLoader0();
  10.127 -        if (cl==null) {
  10.128 -            // A system class.
  10.129 -            return ClassLoader.getSystemResourceAsStream(name);
  10.130 -        }
  10.131 -        return cl.getResourceAsStream(name);
  10.132 -    }
  10.133 +        byte[] arr = getResourceAsStream0(name);
  10.134 +        return arr == null ? null : new ByteArrayInputStream(arr);
  10.135 +     }
  10.136 +     
  10.137 +     @JavaScriptBody(args = "name", body = 
  10.138 +         "return (vm.loadBytes) ? vm.loadBytes(name) : null;"
  10.139 +     )
  10.140 +     private static native byte[] getResourceAsStream0(String name);
  10.141  
  10.142      /**
  10.143       * Finds a resource with a given name.  The rules for searching resources
  10.144 @@ -890,7 +927,7 @@
  10.145       */
  10.146      public java.net.URL getResource(String name) {
  10.147          name = resolveName(name);
  10.148 -        ClassLoader cl = getClassLoader0();
  10.149 +        ClassLoader cl = null;
  10.150          if (cl==null) {
  10.151              // A system class.
  10.152              return ClassLoader.getSystemResource(name);
  10.153 @@ -954,9 +991,6 @@
  10.154          throw new SecurityException();
  10.155      }
  10.156      
  10.157 -    // Package-private to allow ClassLoader access
  10.158 -    native ClassLoader getClassLoader0();    
  10.159 -
  10.160      /**
  10.161       * Returns the {@code Class} representing the component type of an
  10.162       * array.  If this class does not represent an array class this method
  10.163 @@ -1090,10 +1124,13 @@
  10.164          throw new UnsupportedOperationException();
  10.165      }
  10.166  
  10.167 -    static Class getPrimitiveClass(String type) {
  10.168 -        // XXX
  10.169 -        return Object.class;
  10.170 -    }
  10.171 +    @JavaScriptBody(args = "type", body = ""
  10.172 +        + "var c = vm.java_lang_Class(true);"
  10.173 +        + "c.jvmName = type;"
  10.174 +        + "c.primitive = true;"
  10.175 +        + "return c;"
  10.176 +    )
  10.177 +    native static Class getPrimitiveClass(String type);
  10.178  
  10.179      public boolean desiredAssertionStatus() {
  10.180          return false;
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/emul/src/main/java/java/lang/NoSuchMethodException.java	Fri Jan 11 16:36:28 2013 +0100
    11.3 @@ -0,0 +1,53 @@
    11.4 +/*
    11.5 + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.  Oracle designates this
   11.11 + * particular file as subject to the "Classpath" exception as provided
   11.12 + * by Oracle in the LICENSE file that accompanied this code.
   11.13 + *
   11.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.17 + * version 2 for more details (a copy is included in the LICENSE file that
   11.18 + * accompanied this code).
   11.19 + *
   11.20 + * You should have received a copy of the GNU General Public License version
   11.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.23 + *
   11.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.25 + * or visit www.oracle.com if you need additional information or have any
   11.26 + * questions.
   11.27 + */
   11.28 +
   11.29 +package java.lang;
   11.30 +
   11.31 +/**
   11.32 + * Thrown when a particular method cannot be found.
   11.33 + *
   11.34 + * @author     unascribed
   11.35 + * @since      JDK1.0
   11.36 + */
   11.37 +public
   11.38 +class NoSuchMethodException extends ReflectiveOperationException {
   11.39 +    private static final long serialVersionUID = 5034388446362600923L;
   11.40 +
   11.41 +    /**
   11.42 +     * Constructs a <code>NoSuchMethodException</code> without a detail message.
   11.43 +     */
   11.44 +    public NoSuchMethodException() {
   11.45 +        super();
   11.46 +    }
   11.47 +
   11.48 +    /**
   11.49 +     * Constructs a <code>NoSuchMethodException</code> with a detail message.
   11.50 +     *
   11.51 +     * @param      s   the detail message.
   11.52 +     */
   11.53 +    public NoSuchMethodException(String s) {
   11.54 +        super(s);
   11.55 +    }
   11.56 +}
    12.1 --- a/emul/src/main/java/java/lang/Object.java	Fri Jan 11 16:07:55 2013 +0100
    12.2 +++ b/emul/src/main/java/java/lang/Object.java	Fri Jan 11 16:36:28 2013 +0100
    12.3 @@ -221,7 +221,28 @@
    12.4       *               be cloned.
    12.5       * @see java.lang.Cloneable
    12.6       */
    12.7 -    protected native Object clone() throws CloneNotSupportedException;
    12.8 +    protected Object clone() throws CloneNotSupportedException {
    12.9 +        Object ret = clone(this);
   12.10 +        if (ret == null) {
   12.11 +            throw new CloneNotSupportedException(getClass().getName());
   12.12 +        }
   12.13 +        return ret;
   12.14 +    }
   12.15 +
   12.16 +    @JavaScriptBody(args = "self", body = 
   12.17 +          "\nif (!self.$instOf_java_lang_Cloneable) {"
   12.18 +        + "\n  return null;"
   12.19 +        + "\n} else {"
   12.20 +        + "\n  var clone = self.constructor(true);"
   12.21 +        + "\n  var props = Object.getOwnPropertyNames(self);"
   12.22 +        + "\n  for (var i = 0; i < props.length; i++) {"
   12.23 +        + "\n    var p = props[i];"
   12.24 +        + "\n    clone[p] = self[p];"
   12.25 +        + "\n  };"
   12.26 +        + "\n  return clone;"
   12.27 +        + "\n}"
   12.28 +    )
   12.29 +    private static native Object clone(Object self) throws CloneNotSupportedException;
   12.30  
   12.31      /**
   12.32       * Returns a string representation of the object. In general, the
    13.1 --- a/emul/src/main/java/java/lang/String.java	Fri Jan 11 16:07:55 2013 +0100
    13.2 +++ b/emul/src/main/java/java/lang/String.java	Fri Jan 11 16:36:28 2013 +0100
    13.3 @@ -1769,60 +1769,7 @@
    13.4      @JavaScriptBody(args = { "self", "str", "fromIndex" }, body =
    13.5          "return self.toString().indexOf(str.toString(), fromIndex);"
    13.6      )
    13.7 -    public int indexOf(String str, int fromIndex) {
    13.8 -        return indexOf(toCharArray(), offset(), length(), str.toCharArray(), str.offset(), str.length(), fromIndex);
    13.9 -    }
   13.10 -
   13.11 -    /**
   13.12 -     * Code shared by String and StringBuffer to do searches. The
   13.13 -     * source is the character array being searched, and the target
   13.14 -     * is the string being searched for.
   13.15 -     *
   13.16 -     * @param   source       the characters being searched.
   13.17 -     * @param   sourceOffset offset of the source string.
   13.18 -     * @param   sourceCount  count of the source string.
   13.19 -     * @param   target       the characters being searched for.
   13.20 -     * @param   targetOffset offset of the target string.
   13.21 -     * @param   targetCount  count of the target string.
   13.22 -     * @param   fromIndex    the index to begin searching from.
   13.23 -     */
   13.24 -    static int indexOf(char[] source, int sourceOffset, int sourceCount,
   13.25 -                       char[] target, int targetOffset, int targetCount,
   13.26 -                       int fromIndex) {
   13.27 -        if (fromIndex >= sourceCount) {
   13.28 -            return (targetCount == 0 ? sourceCount : -1);
   13.29 -        }
   13.30 -        if (fromIndex < 0) {
   13.31 -            fromIndex = 0;
   13.32 -        }
   13.33 -        if (targetCount == 0) {
   13.34 -            return fromIndex;
   13.35 -        }
   13.36 -
   13.37 -        char first  = target[targetOffset];
   13.38 -        int max = sourceOffset + (sourceCount - targetCount);
   13.39 -
   13.40 -        for (int i = sourceOffset + fromIndex; i <= max; i++) {
   13.41 -            /* Look for first character. */
   13.42 -            if (source[i] != first) {
   13.43 -                while (++i <= max && source[i] != first);
   13.44 -            }
   13.45 -
   13.46 -            /* Found first character, now look at the rest of v2 */
   13.47 -            if (i <= max) {
   13.48 -                int j = i + 1;
   13.49 -                int end = j + targetCount - 1;
   13.50 -                for (int k = targetOffset + 1; j < end && source[j] ==
   13.51 -                         target[k]; j++, k++);
   13.52 -
   13.53 -                if (j == end) {
   13.54 -                    /* Found whole string. */
   13.55 -                    return i - sourceOffset;
   13.56 -                }
   13.57 -            }
   13.58 -        }
   13.59 -        return -1;
   13.60 -    }
   13.61 +    public native int indexOf(String str, int fromIndex);
   13.62  
   13.63      /**
   13.64       * Returns the index within this string of the last occurrence of the
    14.1 --- a/emul/src/main/java/java/lang/StringBuffer.java	Fri Jan 11 16:07:55 2013 +0100
    14.2 +++ b/emul/src/main/java/java/lang/StringBuffer.java	Fri Jan 11 16:36:28 2013 +0100
    14.3 @@ -527,8 +527,7 @@
    14.4       * @since      1.4
    14.5       */
    14.6      public synchronized int indexOf(String str, int fromIndex) {
    14.7 -        return String.indexOf(value, 0, count,
    14.8 -                              str.toCharArray(), 0, str.length(), fromIndex);
    14.9 +        return super.indexOf(str, fromIndex);
   14.10      }
   14.11  
   14.12      /**
    15.1 --- a/emul/src/main/java/java/lang/StringBuilder.java	Fri Jan 11 16:07:55 2013 +0100
    15.2 +++ b/emul/src/main/java/java/lang/StringBuilder.java	Fri Jan 11 16:36:28 2013 +0100
    15.3 @@ -376,8 +376,7 @@
    15.4       * @throws NullPointerException {@inheritDoc}
    15.5       */
    15.6      public int indexOf(String str, int fromIndex) {
    15.7 -        return String.indexOf(value, 0, count,
    15.8 -                              str.toCharArray(), 0, str.length(), fromIndex);
    15.9 +        return super.indexOf(str, fromIndex);
   15.10      }
   15.11  
   15.12      /**
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/emul/src/main/java/java/lang/Void.java	Fri Jan 11 16:36:28 2013 +0100
    16.3 @@ -0,0 +1,49 @@
    16.4 +/*
    16.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    16.7 + *
    16.8 + * This code is free software; you can redistribute it and/or modify it
    16.9 + * under the terms of the GNU General Public License version 2 only, as
   16.10 + * published by the Free Software Foundation.  Oracle designates this
   16.11 + * particular file as subject to the "Classpath" exception as provided
   16.12 + * by Oracle in the LICENSE file that accompanied this code.
   16.13 + *
   16.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   16.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   16.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   16.17 + * version 2 for more details (a copy is included in the LICENSE file that
   16.18 + * accompanied this code).
   16.19 + *
   16.20 + * You should have received a copy of the GNU General Public License version
   16.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   16.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   16.23 + *
   16.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   16.25 + * or visit www.oracle.com if you need additional information or have any
   16.26 + * questions.
   16.27 + */
   16.28 +
   16.29 +package java.lang;
   16.30 +
   16.31 +/**
   16.32 + * The {@code Void} class is an uninstantiable placeholder class to hold a
   16.33 + * reference to the {@code Class} object representing the Java keyword
   16.34 + * void.
   16.35 + *
   16.36 + * @author  unascribed
   16.37 + * @since   JDK1.1
   16.38 + */
   16.39 +public final
   16.40 +class Void {
   16.41 +
   16.42 +    /**
   16.43 +     * The {@code Class} object representing the pseudo-type corresponding to
   16.44 +     * the keyword {@code void}.
   16.45 +     */
   16.46 +    public static final Class<Void> TYPE = Class.getPrimitiveClass("void");
   16.47 +
   16.48 +    /*
   16.49 +     * The Void class cannot be instantiated.
   16.50 +     */
   16.51 +    private Void() {}
   16.52 +}
    17.1 --- a/emul/src/main/java/java/lang/reflect/Method.java	Fri Jan 11 16:07:55 2013 +0100
    17.2 +++ b/emul/src/main/java/java/lang/reflect/Method.java	Fri Jan 11 16:36:28 2013 +0100
    17.3 @@ -26,8 +26,10 @@
    17.4  package java.lang.reflect;
    17.5  
    17.6  import java.lang.annotation.Annotation;
    17.7 +import java.util.Enumeration;
    17.8  import org.apidesign.bck2brwsr.core.JavaScriptBody;
    17.9  import org.apidesign.bck2brwsr.emul.AnnotationImpl;
   17.10 +import org.apidesign.bck2brwsr.emul.MethodImpl;
   17.11  
   17.12  /**
   17.13   * A {@code Method} provides information about, and access to, a single method
   17.14 @@ -56,7 +58,6 @@
   17.15      private final String name;
   17.16      private final Object data;
   17.17      private final String sig;
   17.18 -    private int modifiers;
   17.19  
   17.20     // Generics infrastructure
   17.21  
   17.22 @@ -108,9 +109,12 @@
   17.23       * @see Modifier
   17.24       */
   17.25      public int getModifiers() {
   17.26 -        return modifiers;
   17.27 +        return getAccess(data);
   17.28      }
   17.29 -
   17.30 +    
   17.31 +    @JavaScriptBody(args = "self", body = "return self.access;")
   17.32 +    private static native int getAccess(Object self);
   17.33 +    
   17.34      /**
   17.35       * Returns an array of {@code TypeVariable} objects that represent the
   17.36       * type variables declared by the generic declaration represented by this
   17.37 @@ -137,7 +141,7 @@
   17.38       * @return the return type for the method this object represents
   17.39       */
   17.40      public Class<?> getReturnType() {
   17.41 -        throw new UnsupportedOperationException();
   17.42 +        return MethodImpl.signatureParser(sig).nextElement();
   17.43      }
   17.44  
   17.45      /**
   17.46 @@ -179,8 +183,13 @@
   17.47       * represents
   17.48       */
   17.49      public Class<?>[] getParameterTypes() {
   17.50 -        throw new UnsupportedOperationException();
   17.51 -        //return (Class<?>[]) parameterTypes.clone();
   17.52 +        Class[] arr = new Class[MethodImpl.signatureElements(sig) - 1];
   17.53 +        Enumeration<Class> en = MethodImpl.signatureParser(sig);
   17.54 +        en.nextElement(); // return type
   17.55 +        for (int i = 0; i < arr.length; i++) {
   17.56 +            arr[i] = en.nextElement();
   17.57 +        }
   17.58 +        return arr;
   17.59      }
   17.60  
   17.61      /**
   17.62 @@ -311,14 +320,14 @@
   17.63              sb.append(Field.getTypeName(getReturnType())).append(' ');
   17.64              sb.append(Field.getTypeName(getDeclaringClass())).append('.');
   17.65              sb.append(getName()).append('(');
   17.66 -            /*
   17.67 -            Class<?>[] params = parameterTypes; // avoid clone
   17.68 +            Class<?>[] params = getParameterTypes(); // avoid clone
   17.69              for (int j = 0; j < params.length; j++) {
   17.70                  sb.append(Field.getTypeName(params[j]));
   17.71                  if (j < (params.length - 1))
   17.72                      sb.append(',');
   17.73              }
   17.74              sb.append(')');
   17.75 +            /*
   17.76              Class<?>[] exceptions = exceptionTypes; // avoid clone
   17.77              if (exceptions.length > 0) {
   17.78                  sb.append(" throws ");
   17.79 @@ -488,17 +497,112 @@
   17.80       * @exception ExceptionInInitializerError if the initialization
   17.81       * provoked by this method fails.
   17.82       */
   17.83 -    @JavaScriptBody(args = { "method", "self", "args" }, body =
   17.84 -          "if (args.length > 0) throw 'unsupported now';"
   17.85 -        + "return method.fld_data(self);"
   17.86 -    )
   17.87      public Object invoke(Object obj, Object... args)
   17.88          throws IllegalAccessException, IllegalArgumentException,
   17.89             InvocationTargetException
   17.90      {
   17.91 -        throw new UnsupportedOperationException();
   17.92 +        final boolean isStatic = (getModifiers() & Modifier.STATIC) == 0;
   17.93 +        if (isStatic && obj == null) {
   17.94 +            throw new NullPointerException();
   17.95 +        }
   17.96 +        Class[] types = getParameterTypes();
   17.97 +        if (types.length != args.length) {
   17.98 +            throw new IllegalArgumentException("Types len " + types.length + " args: " + args.length);
   17.99 +        } else {
  17.100 +            args = args.clone();
  17.101 +            for (int i = 0; i < types.length; i++) {
  17.102 +                Class c = types[i];
  17.103 +                if (c.isPrimitive()) {
  17.104 +                    args[i] = toPrimitive(c, args[i]);
  17.105 +                }
  17.106 +            }
  17.107 +        }
  17.108 +        Object res = invoke0(isStatic, this, obj, args);
  17.109 +        if (getReturnType().isPrimitive()) {
  17.110 +            res = fromPrimitive(getReturnType(), res);
  17.111 +        }
  17.112 +        return res;
  17.113      }
  17.114 +    
  17.115 +    @JavaScriptBody(args = { "st", "method", "self", "args" }, body =
  17.116 +          "var p;\n"
  17.117 +        + "if (st) {\n"
  17.118 +        + "  p = new Array(1);\n"
  17.119 +        + "  p[0] = self;\n"
  17.120 +        + "  p = p.concat(args);\n"
  17.121 +        + "} else {\n"
  17.122 +        + "  p = args;\n"
  17.123 +        + "}\n"
  17.124 +        + "return method.fld_data.apply(self, p);\n"
  17.125 +    )
  17.126 +    private static native Object invoke0(boolean isStatic, Method m, Object self, Object[] args);
  17.127  
  17.128 +    private static Object fromPrimitive(Class<?> type, Object o) {
  17.129 +        if (type == Integer.TYPE) {
  17.130 +            return fromRaw(Integer.class, "valueOf__Ljava_lang_Integer_2I", o);
  17.131 +        }
  17.132 +        if (type == Long.TYPE) {
  17.133 +            return fromRaw(Long.class, "valueOf__Ljava_lang_Long_2J", o);
  17.134 +        }
  17.135 +        if (type == Double.TYPE) {
  17.136 +            return fromRaw(Double.class, "valueOf__Ljava_lang_Double_2D", o);
  17.137 +        }
  17.138 +        if (type == Float.TYPE) {
  17.139 +            return fromRaw(Float.class, "valueOf__Ljava_lang_Float_2F", o);
  17.140 +        }
  17.141 +        if (type == Byte.TYPE) {
  17.142 +            return fromRaw(Byte.class, "valueOf__Ljava_lang_Byte_2B", o);
  17.143 +        }
  17.144 +        if (type == Boolean.TYPE) {
  17.145 +            return fromRaw(Boolean.class, "valueOf__Ljava_lang_Boolean_2Z", o);
  17.146 +        }
  17.147 +        if (type == Short.TYPE) {
  17.148 +            return fromRaw(Short.class, "valueOf__Ljava_lang_Short_2S", o);
  17.149 +        }
  17.150 +        if (type.getName().equals("void")) {
  17.151 +            return null;
  17.152 +        }
  17.153 +        throw new IllegalStateException("Can't convert " + o);
  17.154 +    }
  17.155 +    
  17.156 +    @JavaScriptBody(args = { "cls", "m", "o" }, 
  17.157 +        body = "return cls.cnstr(false)[m](o);"
  17.158 +    )
  17.159 +    private static native Integer fromRaw(Class<?> cls, String m, Object o);
  17.160 +
  17.161 +    private static Object toPrimitive(Class<?> type, Object o) {
  17.162 +        if (type == Integer.TYPE) {
  17.163 +            return toRaw("intValue__I", o);
  17.164 +        }
  17.165 +        if (type == Long.TYPE) {
  17.166 +            return toRaw("longValue__J", o);
  17.167 +        }
  17.168 +        if (type == Double.TYPE) {
  17.169 +            return toRaw("doubleValue__D", o);
  17.170 +        }
  17.171 +        if (type == Float.TYPE) {
  17.172 +            return toRaw("floatValue__F", o);
  17.173 +        }
  17.174 +        if (type == Byte.TYPE) {
  17.175 +            return toRaw("byteValue__B", o);
  17.176 +        }
  17.177 +        if (type == Boolean.TYPE) {
  17.178 +            return toRaw("booleanValue__Z", o);
  17.179 +        }
  17.180 +        if (type == Short.TYPE) {
  17.181 +            return toRaw("shortValue__S", o);
  17.182 +        }
  17.183 +        if (type.getName().equals("void")) {
  17.184 +            return o;
  17.185 +        }
  17.186 +        throw new IllegalStateException("Can't convert " + o);
  17.187 +    }
  17.188 +    
  17.189 +    @JavaScriptBody(args = { "m", "o" }, 
  17.190 +        body = "return o[m](o);"
  17.191 +    )
  17.192 +    private static native Object toRaw(String m, Object o);
  17.193 +    
  17.194      /**
  17.195       * Returns {@code true} if this method is a bridge
  17.196       * method; returns {@code false} otherwise.
  17.197 @@ -599,57 +703,12 @@
  17.198      public Annotation[][] getParameterAnnotations() {
  17.199          throw new UnsupportedOperationException();
  17.200      }
  17.201 -    
  17.202 -    //
  17.203 -    // bck2brwsr implementation
  17.204 -    //
  17.205  
  17.206 -    @JavaScriptBody(args = { "clazz", "prefix" },
  17.207 -        body = ""
  17.208 -        + "var c = clazz.cnstr.prototype;"
  17.209 -        + "var arr = new Array();\n"
  17.210 -        + "for (m in c) {\n"
  17.211 -        + "  if (m.indexOf(prefix) === 0) {\n"
  17.212 -        + "     arr.push(m);\n"
  17.213 -        + "     arr.push(c[m]);\n"
  17.214 -        + "  }"
  17.215 -        + "}\n"
  17.216 -        + "return arr;"
  17.217 -    )
  17.218 -    private static native Object[] findMethodData(
  17.219 -        Class<?> clazz, String prefix
  17.220 -    );
  17.221 -
  17.222 -    // XXX should not be public
  17.223 -    public static Method findMethod(
  17.224 -        Class<?> clazz, String name, Class<?>... parameterTypes
  17.225 -    ) {
  17.226 -        Object[] data = findMethodData(clazz, name + "__");
  17.227 -        if (data.length == 0) {
  17.228 -            return null;
  17.229 -        }
  17.230 -        String sig = ((String)data[0]).substring(name.length() + 2);
  17.231 -        return new Method(clazz, name, data[1], sig);
  17.232 -    }
  17.233 -    
  17.234 -    public static Method[] findMethods(Class<?> clazz) {
  17.235 -        Object[] namesAndData = findMethodData(clazz, "");
  17.236 -        int cnt = 0;
  17.237 -        for (int i = 0; i < namesAndData.length; i += 2) {
  17.238 -            String sig = (String) namesAndData[i];
  17.239 -            Object data = namesAndData[i + 1];
  17.240 -            int middle = sig.indexOf("__");
  17.241 -            if (middle == -1) {
  17.242 -                continue;
  17.243 +    static {
  17.244 +        MethodImpl.INSTANCE = new MethodImpl() {
  17.245 +            protected Method create(Class<?> declaringClass, String name, Object data, String sig) {
  17.246 +                return new Method(declaringClass, name, data, sig);
  17.247              }
  17.248 -            String name = sig.substring(0, middle);
  17.249 -            sig = sig.substring(middle + 2);
  17.250 -            namesAndData[cnt++] = new Method(clazz, name, data, sig);
  17.251 -        }
  17.252 -        Method[] arr = new Method[cnt];
  17.253 -        for (int i = 0; i < cnt; i++) {
  17.254 -            arr[i] = (Method)namesAndData[i];
  17.255 -        }
  17.256 -        return arr;
  17.257 +        };
  17.258      }
  17.259  }
    18.1 --- a/emul/src/main/java/java/net/URL.java	Fri Jan 11 16:07:55 2013 +0100
    18.2 +++ b/emul/src/main/java/java/net/URL.java	Fri Jan 11 16:36:28 2013 +0100
    18.3 @@ -27,6 +27,7 @@
    18.4  
    18.5  import java.io.IOException;
    18.6  import java.io.InputStream;
    18.7 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
    18.8  
    18.9  /**
   18.10   * Class <code>URL</code> represents a Uniform Resource
   18.11 @@ -964,9 +965,16 @@
   18.12       * @see        java.net.URLConnection#getContent()
   18.13       */
   18.14      public final Object getContent() throws java.io.IOException {
   18.15 -        throw new IOException();
   18.16 -//        return openConnection().getContent();
   18.17 +        return loadText(toExternalForm());
   18.18      }
   18.19 +    
   18.20 +    @JavaScriptBody(args = "url", body = ""
   18.21 +        + "var request = new XMLHttpRequest();\n"
   18.22 +        + "request.open('GET', url, false);\n"
   18.23 +        + "request.send();\n"
   18.24 +        + "return request.responseText;\n"
   18.25 +    )
   18.26 +    private static native String loadText(String url) throws IOException;
   18.27  
   18.28      /**
   18.29       * Gets the contents of this URL. This method is a shorthand for:
   18.30 @@ -984,8 +992,12 @@
   18.31       */
   18.32      public final Object getContent(Class[] classes)
   18.33      throws java.io.IOException {
   18.34 -        throw new IOException();
   18.35 -//        return openConnection().getContent(classes);
   18.36 +        for (Class<?> c : classes) {
   18.37 +            if (c == String.class) {
   18.38 +                return getContent();
   18.39 +            }
   18.40 +        }
   18.41 +        return null;
   18.42      }
   18.43  
   18.44      static URLStreamHandler getURLStreamHandler(String protocol) {
    19.1 --- a/emul/src/main/java/org/apidesign/bck2brwsr/emul/AnnotationImpl.java	Fri Jan 11 16:07:55 2013 +0100
    19.2 +++ b/emul/src/main/java/org/apidesign/bck2brwsr/emul/AnnotationImpl.java	Fri Jan 11 16:36:28 2013 +0100
    19.3 @@ -1,6 +1,19 @@
    19.4 -/*
    19.5 - * To change this template, choose Tools | Templates
    19.6 - * and open the template in the editor.
    19.7 +/**
    19.8 + * Back 2 Browser Bytecode Translator
    19.9 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   19.10 + *
   19.11 + * This program is free software: you can redistribute it and/or modify
   19.12 + * it under the terms of the GNU General Public License as published by
   19.13 + * the Free Software Foundation, version 2 of the License.
   19.14 + *
   19.15 + * This program is distributed in the hope that it will be useful,
   19.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.18 + * GNU General Public License for more details.
   19.19 + *
   19.20 + * You should have received a copy of the GNU General Public License
   19.21 + * along with this program. Look for COPYING file in the top folder.
   19.22 + * If not, see http://opensource.org/licenses/GPL-2.0.
   19.23   */
   19.24  package org.apidesign.bck2brwsr.emul;
   19.25  
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/emul/src/main/java/org/apidesign/bck2brwsr/emul/MethodImpl.java	Fri Jan 11 16:36:28 2013 +0100
    20.3 @@ -0,0 +1,162 @@
    20.4 +/*
    20.5 + * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
    20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.7 + *
    20.8 + * This code is free software; you can redistribute it and/or modify it
    20.9 + * under the terms of the GNU General Public License version 2 only, as
   20.10 + * published by the Free Software Foundation.  Oracle designates this
   20.11 + * particular file as subject to the "Classpath" exception as provided
   20.12 + * by Oracle in the LICENSE file that accompanied this code.
   20.13 + *
   20.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   20.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   20.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   20.17 + * version 2 for more details (a copy is included in the LICENSE file that
   20.18 + * accompanied this code).
   20.19 + *
   20.20 + * You should have received a copy of the GNU General Public License version
   20.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   20.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20.23 + *
   20.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   20.25 + * or visit www.oracle.com if you need additional information or have any
   20.26 + * questions.
   20.27 + */
   20.28 +package org.apidesign.bck2brwsr.emul;
   20.29 +
   20.30 +import java.lang.reflect.Method;
   20.31 +import java.util.Enumeration;
   20.32 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   20.33 +
   20.34 +/** Utilities to work on methods.
   20.35 + *
   20.36 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   20.37 + */
   20.38 +public abstract class MethodImpl {
   20.39 +    public static MethodImpl INSTANCE;
   20.40 +    static {
   20.41 +        try {
   20.42 +            Class.forName(Method.class.getName());
   20.43 +        } catch (ClassNotFoundException ex) {
   20.44 +            throw new IllegalStateException(ex);
   20.45 +        }
   20.46 +    }
   20.47 +    
   20.48 +    protected abstract Method create(Class<?> declaringClass, String name, Object data, String sig);
   20.49 +    
   20.50 +    
   20.51 +    //
   20.52 +    // bck2brwsr implementation
   20.53 +    //
   20.54 +
   20.55 +    @JavaScriptBody(args = {"clazz", "prefix"},
   20.56 +        body = ""
   20.57 +        + "var c = clazz.cnstr.prototype;"
   20.58 +        + "var arr = new Array();\n"
   20.59 +        + "for (m in c) {\n"
   20.60 +        + "  if (m.indexOf(prefix) === 0) {\n"
   20.61 +        + "     arr.push(m);\n"
   20.62 +        + "     arr.push(c[m]);\n"
   20.63 +        + "  }"
   20.64 +        + "}\n"
   20.65 +        + "return arr;")
   20.66 +    private static native Object[] findMethodData(
   20.67 +        Class<?> clazz, String prefix);
   20.68 +
   20.69 +    public static Method findMethod(
   20.70 +        Class<?> clazz, String name, Class<?>... parameterTypes) {
   20.71 +        Object[] data = findMethodData(clazz, name + "__");
   20.72 +        BIG: for (int i = 0; i < data.length; i += 2) {
   20.73 +            String sig = ((String) data[0]).substring(name.length() + 2);
   20.74 +            Method tmp = INSTANCE.create(clazz, name, data[1], sig);
   20.75 +            Class<?>[] tmpParms = tmp.getParameterTypes();
   20.76 +            if (parameterTypes.length != tmpParms.length) {
   20.77 +                continue;
   20.78 +            }
   20.79 +            for (int j = 0; j < tmpParms.length; j++) {
   20.80 +                if (!parameterTypes[j].equals(tmpParms[j])) {
   20.81 +                    continue BIG;
   20.82 +                }
   20.83 +            }
   20.84 +            return tmp;
   20.85 +        }
   20.86 +        return null;
   20.87 +    }
   20.88 +
   20.89 +    public static Method[] findMethods(Class<?> clazz, int mask) {
   20.90 +        Object[] namesAndData = findMethodData(clazz, "");
   20.91 +        int cnt = 0;
   20.92 +        for (int i = 0; i < namesAndData.length; i += 2) {
   20.93 +            String sig = (String) namesAndData[i];
   20.94 +            Object data = namesAndData[i + 1];
   20.95 +            int middle = sig.indexOf("__");
   20.96 +            if (middle == -1) {
   20.97 +                continue;
   20.98 +            }
   20.99 +            String name = sig.substring(0, middle);
  20.100 +            sig = sig.substring(middle + 2);
  20.101 +            final Method m = INSTANCE.create(clazz, name, data, sig);
  20.102 +            if ((m.getModifiers() & mask) == 0) {
  20.103 +                continue;
  20.104 +            }
  20.105 +            namesAndData[cnt++] = m;
  20.106 +        }
  20.107 +        Method[] arr = new Method[cnt];
  20.108 +        for (int i = 0; i < cnt; i++) {
  20.109 +            arr[i] = (Method) namesAndData[i];
  20.110 +        }
  20.111 +        return arr;
  20.112 +    }
  20.113 +
  20.114 +    public static int signatureElements(String sig) {
  20.115 +        Enumeration<Class> en = signatureParser(sig);
  20.116 +        int cnt = 0;
  20.117 +        while (en.hasMoreElements()) {
  20.118 +            en.nextElement();
  20.119 +            cnt++;
  20.120 +        }
  20.121 +        return cnt;
  20.122 +    }
  20.123 +    
  20.124 +    public static Enumeration<Class> signatureParser(final String sig) {
  20.125 +        class E implements Enumeration<Class> {
  20.126 +            int pos;
  20.127 +            
  20.128 +            public boolean hasMoreElements() {
  20.129 +                return pos < sig.length();
  20.130 +            }
  20.131 +
  20.132 +            public Class nextElement() {
  20.133 +                switch (sig.charAt(pos++)) {
  20.134 +                    case 'I':
  20.135 +                        return Integer.TYPE;
  20.136 +                    case 'J':
  20.137 +                        return Long.TYPE;
  20.138 +                    case 'D':
  20.139 +                        return Double.TYPE;
  20.140 +                    case 'F':
  20.141 +                        return Float.TYPE;
  20.142 +                    case 'B':
  20.143 +                        return Byte.TYPE;
  20.144 +                    case 'Z':
  20.145 +                        return Boolean.TYPE;
  20.146 +                    case 'S':
  20.147 +                        return Short.TYPE;
  20.148 +                    case 'V':
  20.149 +                        return Void.TYPE;
  20.150 +                    case 'L':
  20.151 +                        try {
  20.152 +                            int up = sig.indexOf("_2");
  20.153 +                            String type = sig.substring(1, up);
  20.154 +                            pos = up + 2;
  20.155 +                            return Class.forName(type);
  20.156 +                        } catch (ClassNotFoundException ex) {
  20.157 +                            // should not happen
  20.158 +                        }
  20.159 +                }
  20.160 +                throw new UnsupportedOperationException(sig + " at " + pos);
  20.161 +            }
  20.162 +        }
  20.163 +        return new E();
  20.164 +    }
  20.165 +}
    21.1 --- a/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js	Fri Jan 11 16:07:55 2013 +0100
    21.2 +++ b/emul/src/main/resources/org/apidesign/vm4brwsr/emul/java_lang_String.js	Fri Jan 11 16:36:28 2013 +0100
    21.3 @@ -6,4 +6,11 @@
    21.4    for(var i = 0; i < this.length; i++) this[i] = null;
    21.5    return this;
    21.6  };
    21.7 -
    21.8 +Array.prototype.clone__Ljava_lang_Object_2 = function() {
    21.9 +  var s = this.length;
   21.10 +  var ret = new Array(s);
   21.11 +  for (var i = 0; i < s; i++) {
   21.12 +      ret[i] = this[i];
   21.13 +  }
   21.14 +  return ret;
   21.15 +};
    22.1 --- a/javap/src/main/java/org/apidesign/javap/ClassData.java	Fri Jan 11 16:07:55 2013 +0100
    22.2 +++ b/javap/src/main/java/org/apidesign/javap/ClassData.java	Fri Jan 11 16:36:28 2013 +0100
    22.3 @@ -326,6 +326,10 @@
    22.4              return res; // "#"+cpx+"// ERROR IN DISASSEMBLER";
    22.5          }
    22.6      }
    22.7 +    
    22.8 +    public int getAccessFlags() {
    22.9 +        return access;
   22.10 +    }
   22.11  
   22.12      /**
   22.13       * Returns true if it is a class
    23.1 --- a/javap/src/main/java/org/apidesign/javap/Hashtable.java	Fri Jan 11 16:07:55 2013 +0100
    23.2 +++ b/javap/src/main/java/org/apidesign/javap/Hashtable.java	Fri Jan 11 16:36:28 2013 +0100
    23.3 @@ -1,11 +1,22 @@
    23.4 -/*
    23.5 - * To change this template, choose Tools | Templates
    23.6 - * and open the template in the editor.
    23.7 +/**
    23.8 + * Back 2 Browser Bytecode Translator
    23.9 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   23.10 + *
   23.11 + * This program is free software: you can redistribute it and/or modify
   23.12 + * it under the terms of the GNU General Public License as published by
   23.13 + * the Free Software Foundation, version 2 of the License.
   23.14 + *
   23.15 + * This program is distributed in the hope that it will be useful,
   23.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.18 + * GNU General Public License for more details.
   23.19 + *
   23.20 + * You should have received a copy of the GNU General Public License
   23.21 + * along with this program. Look for COPYING file in the top folder.
   23.22 + * If not, see http://opensource.org/licenses/GPL-2.0.
   23.23   */
   23.24  package org.apidesign.javap;
   23.25  
   23.26 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
   23.27 -
   23.28  /** A JavaScript optimized replacement for Hashtable.
   23.29   *
   23.30   * @author Jaroslav Tulach <jtulach@netbeans.org>
   23.31 @@ -25,9 +36,6 @@
   23.32      Hashtable() {
   23.33      }
   23.34  
   23.35 -    @JavaScriptBody(args = { "self", "key", "val" }, body = 
   23.36 -        "self[key] = val;"
   23.37 -    )
   23.38      synchronized void put(Object key, Object val) {
   23.39          int[] where = { -1, -1 };
   23.40          Object found = get(key, where);
   23.41 @@ -61,9 +69,6 @@
   23.42          }
   23.43      }
   23.44  
   23.45 -    @JavaScriptBody(args = {"self", "key" }, body = 
   23.46 -        "return self[key];"
   23.47 -    )
   23.48      Object get(Object key) {
   23.49          return get(key, null);
   23.50      }
    24.1 --- a/javap/src/main/java/org/apidesign/javap/MethodData.java	Fri Jan 11 16:07:55 2013 +0100
    24.2 +++ b/javap/src/main/java/org/apidesign/javap/MethodData.java	Fri Jan 11 16:36:28 2013 +0100
    24.3 @@ -25,9 +25,9 @@
    24.4  
    24.5  package org.apidesign.javap;
    24.6  
    24.7 -import java.io.*;
    24.8 -import org.apidesign.bck2brwsr.core.JavaScriptBody;
    24.9  
   24.10 +import java.io.DataInputStream;
   24.11 +import java.io.IOException;
   24.12  import static org.apidesign.javap.RuntimeConstants.*;
   24.13  
   24.14  /**
   24.15 @@ -235,22 +235,8 @@
   24.16      /**
   24.17       * Return access of the method.
   24.18       */
   24.19 -    public String[] getAccess(){
   24.20 -
   24.21 -        Vector v = new Vector();
   24.22 -        if ((access & ACC_PUBLIC)   !=0) v.addElement("public");
   24.23 -        if ((access & ACC_PRIVATE)   !=0) v.addElement("private");
   24.24 -        if ((access & ACC_PROTECTED)   !=0) v.addElement("protected");
   24.25 -        if ((access & ACC_STATIC)   !=0) v.addElement("static");
   24.26 -        if ((access & ACC_FINAL)    !=0) v.addElement("final");
   24.27 -        if ((access & ACC_SYNCHRONIZED) !=0) v.addElement("synchronized");
   24.28 -        if ((access & ACC_NATIVE) !=0) v.addElement("native");
   24.29 -        if ((access & ACC_ABSTRACT) !=0) v.addElement("abstract");
   24.30 -        if ((access & ACC_STRICT) !=0) v.addElement("strictfp");
   24.31 -
   24.32 -        String[] accflags = new String[v.size()];
   24.33 -        v.copyInto(accflags);
   24.34 -        return accflags;
   24.35 +    public int getAccess(){
   24.36 +        return access;
   24.37      }
   24.38  
   24.39      /**
   24.40 @@ -357,10 +343,10 @@
   24.41      /**
   24.42       * Return exception table in code attributre.
   24.43       */
   24.44 -    public Vector getexception_table(){
   24.45 -        return exception_table;
   24.46 +    public TrapDataIterator getTrapDataIterator(){
   24.47 +        return new TrapDataIterator(exception_table);
   24.48      }
   24.49 -
   24.50 +    
   24.51  
   24.52      /**
   24.53       * Return method attributes.
   24.54 @@ -401,4 +387,8 @@
   24.55          attrs.copyInto(arr);
   24.56          return ClassData.findAttr(n, arr);
   24.57      }
   24.58 +
   24.59 +    public boolean isConstructor() {
   24.60 +        return "<init>".equals(getName());
   24.61 +    }
   24.62  }
    25.1 --- a/javap/src/main/java/org/apidesign/javap/TrapData.java	Fri Jan 11 16:07:55 2013 +0100
    25.2 +++ b/javap/src/main/java/org/apidesign/javap/TrapData.java	Fri Jan 11 16:36:28 2013 +0100
    25.3 @@ -26,7 +26,6 @@
    25.4  
    25.5  package org.apidesign.javap;
    25.6  
    25.7 -import java.util.*;
    25.8  import java.io.*;
    25.9  
   25.10  /**
   25.11 @@ -34,15 +33,18 @@
   25.12   *
   25.13   * @author  Sucheta Dambalkar (Adopted code from jdis)
   25.14   */
   25.15 -class TrapData {
   25.16 -    short start_pc, end_pc, handler_pc, catch_cpx;
   25.17 -  int num;
   25.18 +public final class TrapData {
   25.19 +  public final short start_pc;
   25.20 +  public final short end_pc;
   25.21 +  public final short handler_pc;
   25.22 +  public final short catch_cpx;
   25.23 +  final int num;
   25.24  
   25.25  
   25.26      /**
   25.27       * Read and store exception table data in code attribute.
   25.28       */
   25.29 -    public TrapData(DataInputStream in, int num) throws IOException {
   25.30 +    TrapData(DataInputStream in, int num) throws IOException {
   25.31          this.num=num;
   25.32          start_pc = in.readShort();
   25.33          end_pc=in.readShort();
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/javap/src/main/java/org/apidesign/javap/TrapDataIterator.java	Fri Jan 11 16:36:28 2013 +0100
    26.3 @@ -0,0 +1,114 @@
    26.4 +/**
    26.5 + * Back 2 Browser Bytecode Translator
    26.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    26.7 + *
    26.8 + * This program is free software: you can redistribute it and/or modify
    26.9 + * it under the terms of the GNU General Public License as published by
   26.10 + * the Free Software Foundation, version 2 of the License.
   26.11 + *
   26.12 + * This program is distributed in the hope that it will be useful,
   26.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   26.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   26.15 + * GNU General Public License for more details.
   26.16 + *
   26.17 + * You should have received a copy of the GNU General Public License
   26.18 + * along with this program. Look for COPYING file in the top folder.
   26.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   26.20 + */
   26.21 +package org.apidesign.javap;
   26.22 +
   26.23 +/**
   26.24 + *
   26.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   26.26 + */
   26.27 +public final class TrapDataIterator {
   26.28 +    private final Hashtable exStart = new Hashtable();
   26.29 +    private final Hashtable exStop = new Hashtable();
   26.30 +    private TrapData[] current = new TrapData[10];
   26.31 +    private int currentCount;
   26.32 +    
   26.33 +    TrapDataIterator(Vector exceptionTable) {
   26.34 +        for (int i=0 ; i < exceptionTable.size(); i++) {
   26.35 +            final TrapData td = (TrapData)exceptionTable.elementAt(i);
   26.36 +            put(exStart, td.start_pc, td);
   26.37 +            put(exStop, td.end_pc, td);
   26.38 +        }
   26.39 +    }
   26.40 +    
   26.41 +    private static void put(Hashtable h, short key, TrapData td) {
   26.42 +        Short s = Short.valueOf((short)key);
   26.43 +        Vector v = (Vector) h.get(s);
   26.44 +        if (v == null) {
   26.45 +            v = new Vector(1);
   26.46 +            h.put(s, v);
   26.47 +        }
   26.48 +        v.add(td);
   26.49 +    }
   26.50 +    
   26.51 +    private boolean processAll(Hashtable h, Short key, boolean add) {
   26.52 +        boolean change = false;
   26.53 +        Vector v = (Vector)h.get(key);
   26.54 +        if (v != null) {
   26.55 +            int s = v.size();
   26.56 +            for (int i = 0; i < s; i++) {
   26.57 +                TrapData td = (TrapData)v.elementAt(i);
   26.58 +                if (add) {
   26.59 +                    add(td);
   26.60 +                    change = true;
   26.61 +                } else {
   26.62 +                    remove(td);
   26.63 +                    change = true;
   26.64 +                }
   26.65 +            }
   26.66 +        }
   26.67 +        return change;
   26.68 +    }
   26.69 +    
   26.70 +    public boolean advanceTo(int i) {
   26.71 +        Short s = Short.valueOf((short)i);
   26.72 +        boolean ch1 = processAll(exStart, s, true);
   26.73 +        boolean ch2 = processAll(exStop, s, false);
   26.74 +        return ch1 || ch2;
   26.75 +    }
   26.76 +
   26.77 +    public boolean useTry() {
   26.78 +        return currentCount > 0;
   26.79 +    }
   26.80 +
   26.81 +    public TrapData[] current() {
   26.82 +        TrapData[] copy = new TrapData[currentCount];
   26.83 +        for (int i = 0; i < currentCount; i++) {
   26.84 +            copy[i] = current[i];
   26.85 +        }
   26.86 +        return copy;
   26.87 +    }
   26.88 +
   26.89 +    private void add(TrapData e) {
   26.90 +        if (currentCount == current.length) {
   26.91 +            TrapData[] data = new TrapData[currentCount * 2];
   26.92 +            for (int i = 0; i < currentCount; i++) {
   26.93 +                data[i] = current[i];
   26.94 +            }
   26.95 +            current = data;
   26.96 +        }
   26.97 +        current[currentCount++] = e;
   26.98 +    }
   26.99 +
  26.100 +    private void remove(TrapData e) {
  26.101 +        if (currentCount == 0) {
  26.102 +            return;
  26.103 +        }
  26.104 +        int from = 0;
  26.105 +        while (from < currentCount) {
  26.106 +            if (e == current[from++]) {
  26.107 +                break;
  26.108 +            }
  26.109 +        }
  26.110 +        while (from < currentCount) {
  26.111 +            current[from - 1] = current[from];
  26.112 +            current[from] = null;
  26.113 +            from++;
  26.114 +        }
  26.115 +        currentCount--;
  26.116 +    }
  26.117 +}
    27.1 --- a/javap/src/main/java/org/apidesign/javap/Vector.java	Fri Jan 11 16:07:55 2013 +0100
    27.2 +++ b/javap/src/main/java/org/apidesign/javap/Vector.java	Fri Jan 11 16:36:28 2013 +0100
    27.3 @@ -1,6 +1,19 @@
    27.4 -/*
    27.5 - * To change this template, choose Tools | Templates
    27.6 - * and open the template in the editor.
    27.7 +/**
    27.8 + * Back 2 Browser Bytecode Translator
    27.9 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   27.10 + *
   27.11 + * This program is free software: you can redistribute it and/or modify
   27.12 + * it under the terms of the GNU General Public License as published by
   27.13 + * the Free Software Foundation, version 2 of the License.
   27.14 + *
   27.15 + * This program is distributed in the hope that it will be useful,
   27.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   27.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   27.18 + * GNU General Public License for more details.
   27.19 + *
   27.20 + * You should have received a copy of the GNU General Public License
   27.21 + * along with this program. Look for COPYING file in the top folder.
   27.22 + * If not, see http://opensource.org/licenses/GPL-2.0.
   27.23   */
   27.24  package org.apidesign.javap;
   27.25  
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/javaquery/demo-calculator-dynamic/nbactions.xml	Fri Jan 11 16:36:28 2013 +0100
    28.3 @@ -0,0 +1,29 @@
    28.4 +<?xml version="1.0" encoding="UTF-8"?>
    28.5 +<!--
    28.6 +
    28.7 +    Back 2 Browser Bytecode Translator
    28.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    28.9 +
   28.10 +    This program is free software: you can redistribute it and/or modify
   28.11 +    it under the terms of the GNU General Public License as published by
   28.12 +    the Free Software Foundation, version 2 of the License.
   28.13 +
   28.14 +    This program is distributed in the hope that it will be useful,
   28.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   28.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   28.17 +    GNU General Public License for more details.
   28.18 +
   28.19 +    You should have received a copy of the GNU General Public License
   28.20 +    along with this program. Look for COPYING file in the top folder.
   28.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   28.22 +
   28.23 +-->
   28.24 +<actions>
   28.25 +        <action>
   28.26 +            <actionName>run</actionName>
   28.27 +            <goals>
   28.28 +                <goal>process-classes</goal>
   28.29 +                <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
   28.30 +            </goals>
   28.31 +        </action>
   28.32 +    </actions>
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/javaquery/demo-calculator-dynamic/pom.xml	Fri Jan 11 16:36:28 2013 +0100
    29.3 @@ -0,0 +1,58 @@
    29.4 +<?xml version="1.0"?>
    29.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    29.6 +  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    29.7 +  <modelVersion>4.0.0</modelVersion>
    29.8 +
    29.9 +  <groupId>org.apidesign.bck2brwsr</groupId>
   29.10 +  <artifactId>demo.calculator</artifactId>
   29.11 +  <version>0.3-SNAPSHOT</version>
   29.12 +  <packaging>jar</packaging>
   29.13 +
   29.14 +  <name>JavaQuery Demo - Calculator</name>
   29.15 +  <url>http://maven.apache.org</url>
   29.16 +
   29.17 +  <properties>
   29.18 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   29.19 +  </properties>
   29.20 +  <build>
   29.21 +      <plugins>
   29.22 +            <plugin>
   29.23 +                <groupId>org.apidesign.bck2brwsr</groupId>
   29.24 +                <artifactId>mojo</artifactId>
   29.25 +                <version>0.3-SNAPSHOT</version>
   29.26 +                <executions>
   29.27 +                    <execution>
   29.28 +                        <goals>
   29.29 +                            <goal>brwsr</goal>
   29.30 +                        </goals>
   29.31 +                    </execution>
   29.32 +                </executions>
   29.33 +                <configuration>
   29.34 +                    <startpage>org/apidesign/bck2brwsr/mavenhtml/Calculator.xhtml</startpage>
   29.35 +                </configuration>
   29.36 +            </plugin>
   29.37 +         <plugin>
   29.38 +            <groupId>org.apache.maven.plugins</groupId>
   29.39 +            <artifactId>maven-compiler-plugin</artifactId>
   29.40 +            <version>2.3.2</version>
   29.41 +            <configuration>
   29.42 +               <source>1.7</source>
   29.43 +               <target>1.7</target>
   29.44 +            </configuration>
   29.45 +         </plugin>
   29.46 +      </plugins>
   29.47 +  </build>
   29.48 +
   29.49 +  <dependencies>
   29.50 +    <dependency>
   29.51 +      <groupId>org.apidesign.bck2brwsr</groupId>
   29.52 +      <artifactId>emul</artifactId>
   29.53 +      <version>0.3-SNAPSHOT</version>
   29.54 +    </dependency>
   29.55 +    <dependency>
   29.56 +      <groupId>org.apidesign.bck2brwsr</groupId>
   29.57 +      <artifactId>javaquery.api</artifactId>
   29.58 +      <version>0.3-SNAPSHOT</version>
   29.59 +    </dependency>
   29.60 +  </dependencies>
   29.61 +</project>
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/javaquery/demo-calculator-dynamic/src/main/java/org/apidesign/bck2brwsr/mavenhtml/App.java	Fri Jan 11 16:36:28 2013 +0100
    30.3 @@ -0,0 +1,88 @@
    30.4 +/**
    30.5 + * Back 2 Browser Bytecode Translator
    30.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    30.7 + *
    30.8 + * This program is free software: you can redistribute it and/or modify
    30.9 + * it under the terms of the GNU General Public License as published by
   30.10 + * the Free Software Foundation, version 2 of the License.
   30.11 + *
   30.12 + * This program is distributed in the hope that it will be useful,
   30.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   30.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   30.15 + * GNU General Public License for more details.
   30.16 + *
   30.17 + * You should have received a copy of the GNU General Public License
   30.18 + * along with this program. Look for COPYING file in the top folder.
   30.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   30.20 + */
   30.21 +package org.apidesign.bck2brwsr.mavenhtml;
   30.22 +
   30.23 +import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
   30.24 +import org.apidesign.bck2brwsr.htmlpage.api.Page;
   30.25 +
   30.26 +/** HTML5 & Java demo showing the power of 
   30.27 + * <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation processors</a>
   30.28 + * as well as other goodies.
   30.29 + * 
   30.30 + * @author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
   30.31 + */
   30.32 +@Page(xhtml="Calculator.xhtml")
   30.33 +public class App {
   30.34 +    private static double memory;
   30.35 +    private static String operation;
   30.36 +    
   30.37 +    @OnClick(id="clear")
   30.38 +    static void clear() {
   30.39 +        memory = 0;
   30.40 +        operation = null;
   30.41 +        Calculator.DISPLAY.setValue("0");
   30.42 +    }
   30.43 +    
   30.44 +    @OnClick(id= { "plus", "minus", "mul", "div" })
   30.45 +    static void applyOp(String op) {
   30.46 +        memory = getValue();
   30.47 +        operation = op;
   30.48 +        Calculator.DISPLAY.setValue("0");
   30.49 +    }
   30.50 +    
   30.51 +    @OnClick(id="result")
   30.52 +    static void computeTheValue() {
   30.53 +        switch (operation) {
   30.54 +            case "plus": setValue(memory + getValue()); break;
   30.55 +            case "minus": setValue(memory - getValue()); break;
   30.56 +            case "mul": setValue(memory * getValue()); break;
   30.57 +            case "div": setValue(memory / getValue()); break;
   30.58 +            default: throw new IllegalStateException(operation);
   30.59 +        }
   30.60 +    }
   30.61 +    
   30.62 +    @OnClick(id={"n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7", "n8", "n9"}) 
   30.63 +    static void addDigit(String digit) {
   30.64 +        digit = digit.substring(1);
   30.65 +        String v = Calculator.DISPLAY.getValue();
   30.66 +        if (getValue() == 0.0) {
   30.67 +            Calculator.DISPLAY.setValue(digit);
   30.68 +        } else {
   30.69 +            Calculator.DISPLAY.setValue(v + digit);
   30.70 +        }
   30.71 +    }
   30.72 +    
   30.73 +    private static void setValue(double v) {
   30.74 +        StringBuilder sb = new StringBuilder();
   30.75 +        sb.append(v);
   30.76 +        if (sb.toString().endsWith(".0")) {
   30.77 +            final int l = sb.length();
   30.78 +            sb.delete(l - 2, l);
   30.79 +        }
   30.80 +        Calculator.DISPLAY.setValue(sb.toString());
   30.81 +    }
   30.82 +
   30.83 +    private static double getValue() {
   30.84 +        try {
   30.85 +            return Double.parseDouble(Calculator.DISPLAY.getValue());
   30.86 +        } catch (NumberFormatException ex) {
   30.87 +            Calculator.DISPLAY.setValue("err");
   30.88 +            return 0.0;
   30.89 +        }
   30.90 +    }
   30.91 +}
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/javaquery/demo-calculator-dynamic/src/main/resources/org/apidesign/bck2brwsr/mavenhtml/Calculator.xhtml	Fri Jan 11 16:36:28 2013 +0100
    31.3 @@ -0,0 +1,158 @@
    31.4 +<?xml version="1.0" encoding="UTF-8"?>
    31.5 +<!--
    31.6 +
    31.7 +    Back 2 Browser Bytecode Translator
    31.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    31.9 +
   31.10 +    This program is free software: you can redistribute it and/or modify
   31.11 +    it under the terms of the GNU General Public License as published by
   31.12 +    the Free Software Foundation, version 2 of the License.
   31.13 +
   31.14 +    This program is distributed in the hope that it will be useful,
   31.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   31.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   31.17 +    GNU General Public License for more details.
   31.18 +
   31.19 +    You should have received a copy of the GNU General Public License
   31.20 +    along with this program. Look for COPYING file in the top folder.
   31.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   31.22 +
   31.23 +-->
   31.24 +<!DOCTYPE html>
   31.25 +<html xmlns="http://www.w3.org/1999/xhtml">
   31.26 +    <head>
   31.27 +        <title>Simple Calculator in HTML5 and Java</title>
   31.28 +
   31.29 +        <style type="text/css">
   31.30 +        body {color: #ffffff; background-color: #121e31; font-family: Monospaced}
   31.31 +        pre {color: #ffffff; background-color: #121e31; font-family: Monospaced}
   31.32 +        table {color: #ffffff; background-color: #121e31; font-family: Monospaced}
   31.33 +        .string {color: #e2ce00}
   31.34 +        a {color: #e2ce00}
   31.35 +        .ST1 {color: #0000cc; font-family: Monospaced; font-weight: bold}
   31.36 +        .ST0 {color: #0000ff}
   31.37 +        .comment {color: #428bdd}
   31.38 +        .keyword-directive {color: #f8bb00}
   31.39 +        .tag {color: #f8bb00}
   31.40 +        .ST0 {color: #628fb5; background-color: #1b3450}
   31.41 +        .sgml-comment {color: #808080}
   31.42 +        .value {color: #99006b}
   31.43 +        .argument {color: #007c00}
   31.44 +        .sgml-declaration {color: #bf9221}
   31.45 +        </style>    
   31.46 +        </head>
   31.47 +    <body>
   31.48 +        <h1>Java and HTML5 - Together at Last!</h1>
   31.49 +        <table border="0" cellspacing="2">
   31.50 +            <tbody>
   31.51 +                <tr>
   31.52 +                    <td colspan="4"><input id="display" value="0" 
   31.53 +                            style="text-align: right"/>
   31.54 +                </td>
   31.55 +                </tr>
   31.56 +                <tr>
   31.57 +                    <td><button id="n1">1</button></td>
   31.58 +                    <td><button id="n2">2</button></td>
   31.59 +                    <td><button id="n3">3</button></td>
   31.60 +                    <td><button id="plus">+</button></td>
   31.61 +                </tr>
   31.62 +                <tr>
   31.63 +                    <td><button id="n4">4</button></td>
   31.64 +                    <td><button id="n5">5</button></td>
   31.65 +                    <td><button id="n6">6</button></td>
   31.66 +                    <td><button id="minus">-</button></td>
   31.67 +                </tr>
   31.68 +                <tr>
   31.69 +                    <td><button id="n7">7</button></td>
   31.70 +                    <td><button id="n8">8</button></td>
   31.71 +                    <td><button id="n9">9</button></td>
   31.72 +                    <td><button id="mul">*</button></td>
   31.73 +                </tr>
   31.74 +                <tr>
   31.75 +                    <td><button id="clear">C</button></td>
   31.76 +                    <td><button id="n0">0</button></td>
   31.77 +                    <td><button id="result">=</button></td>
   31.78 +                    <td><button id="div">/</button></td>
   31.79 +                </tr>
   31.80 +            </tbody>
   31.81 +        </table>
   31.82 +
   31.83 +        <script src="/bck2brwsr.js"></script>
   31.84 +        <script src="/vm.js"></script>
   31.85 +        <script type="text/javascript">
   31.86 +            vm.loadClass('org.apidesign.bck2brwsr.mavenhtml.Calculator');
   31.87 +        </script>
   31.88 +        
   31.89 +        <hr/>
   31.90 +    <pre>
   31.91 +    <span class="keyword-directive">package</span> org.apidesign.bck2brwsr.mavenhtml;
   31.92 +
   31.93 +    <span class="keyword-directive">import</span> org.apidesign.bck2brwsr.htmlpage.api.OnClick;
   31.94 +    <span class="keyword-directive">import</span> org.apidesign.bck2brwsr.htmlpage.api.Page;
   31.95 +
   31.96 +    <span class="comment">/**</span> <span class="comment">HTML5</span><span class="comment"> &amp; </span><span class="comment">Java</span> <span class="comment">demo</span> <span class="comment">showing</span> <span class="comment">the</span> <span class="comment">power</span> <span class="comment">of</span> <a href="http://wiki.apidesign.org/wiki/AnnotationProcessor">annotation processors</a>
   31.97 +    <span class="comment"> * </span><span class="comment">as</span> <span class="comment">well</span> <span class="comment">as</span> <span class="comment">other</span> <span class="comment">goodies</span><span class="comment">, including type-safe association between</span>
   31.98 +    <span class="comment"> * </span><span class="comment">an XHTML page and Java.</span>
   31.99 +    <span class="comment"> * </span>
  31.100 +    <span class="comment"> * </span><span class="ST1">@author</span> <span class="comment">Jaroslav</span> <span class="comment">Tulach</span> <span class="ST0">&lt;jaroslav.tulach@apidesign.org&gt;</span>
  31.101 +     <span class="comment">*/</span>
  31.102 +    @Page(xhtml=<span class="string">&quot;</span><span class="string">Calculator.xhtml</span><span class="string">&quot;</span>)
  31.103 +    <span class="keyword-directive">public</span> <span class="keyword-directive">class</span> App {
  31.104 +        <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">double</span> memory;
  31.105 +        <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> String operation;
  31.106 +
  31.107 +        @OnClick(id=<span class="string">&quot;</span><span class="string">clear</span><span class="string">&quot;</span>)
  31.108 +        <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> clear() {
  31.109 +            memory = <span class="number">0</span>;
  31.110 +            operation = <span class="keyword-directive">null</span>;
  31.111 +            Calculator.DISPLAY.setValue(<span class="string">&quot;</span><span class="string">0</span><span class="string">&quot;</span>);
  31.112 +        }
  31.113 +
  31.114 +        @OnClick(id= { <span class="string">&quot;</span><span class="string">plus</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">minus</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">mul</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">div</span><span class="string">&quot;</span> })
  31.115 +        <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> applyOp(String op) {
  31.116 +            memory = getValue();
  31.117 +            operation = op;
  31.118 +            Calculator.DISPLAY.setValue(<span class="string">&quot;</span><span class="string">0</span><span class="string">&quot;</span>);
  31.119 +        }
  31.120 +
  31.121 +        @OnClick(id=<span class="string">&quot;</span><span class="string">result</span><span class="string">&quot;</span>)
  31.122 +        <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> computeTheValue() {
  31.123 +            <span class="keyword-directive">switch</span> (operation) {
  31.124 +                <span class="keyword-directive">case</span> <span class="string">&quot;</span><span class="string">plus</span><span class="string">&quot;</span>: setValue(memory + getValue()); <span class="keyword-directive">break</span>;
  31.125 +                <span class="keyword-directive">case</span> <span class="string">&quot;</span><span class="string">minus</span><span class="string">&quot;</span>: setValue(memory - getValue()); <span class="keyword-directive">break</span>;
  31.126 +                <span class="keyword-directive">case</span> <span class="string">&quot;</span><span class="string">mul</span><span class="string">&quot;</span>: setValue(memory * getValue()); <span class="keyword-directive">break</span>;
  31.127 +                <span class="keyword-directive">case</span> <span class="string">&quot;</span><span class="string">div</span><span class="string">&quot;</span>: setValue(memory / getValue()); <span class="keyword-directive">break</span>;
  31.128 +                <span class="keyword-directive">default</span>: <span class="keyword-directive">throw</span> <span class="keyword-directive">new</span> IllegalStateException(operation);
  31.129 +            }
  31.130 +        }
  31.131 +
  31.132 +        @OnClick(id={<span class="string">&quot;</span><span class="string">n0</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n1</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n2</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n3</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n4</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n5</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n6</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n7</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n8</span><span class="string">&quot;</span>, <span class="string">&quot;</span><span class="string">n9</span><span class="string">&quot;</span>}) 
  31.133 +        <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> addDigit(String digit) {
  31.134 +            digit = digit.substring(<span class="number">1</span>);
  31.135 +            String v = Calculator.DISPLAY.getValue();
  31.136 +            <span class="keyword-directive">if</span> (getValue() == <span class="number">0.0</span>) {
  31.137 +                Calculator.DISPLAY.setValue(digit);
  31.138 +            } <span class="keyword-directive">else</span> {
  31.139 +                Calculator.DISPLAY.setValue(v + digit);
  31.140 +            }
  31.141 +        }
  31.142 +
  31.143 +        <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">void</span> setValue(<span class="keyword-directive">double</span> v) {
  31.144 +            StringBuilder sb = <span class="keyword-directive">new</span> StringBuilder();
  31.145 +            sb.append(v);
  31.146 +            Calculator.DISPLAY.setValue(sb.toString());
  31.147 +        }
  31.148 +
  31.149 +        <span class="keyword-directive">private</span> <span class="keyword-directive">static</span> <span class="keyword-directive">double</span> getValue() {
  31.150 +            <span class="keyword-directive">try</span> {
  31.151 +                <span class="keyword-directive">return</span> Double.parseDouble(Calculator.DISPLAY.getValue());
  31.152 +            } <span class="keyword-directive">catch</span> (NumberFormatException ex) {
  31.153 +                Calculator.DISPLAY.setValue(<span class="string">&quot;</span><span class="string">err</span><span class="string">&quot;</span>);
  31.154 +                <span class="keyword-directive">return</span> <span class="number">0.0</span>;
  31.155 +            }
  31.156 +        }
  31.157 +    }
  31.158 +
  31.159 +    </pre>
  31.160 +    </body>
  31.161 +</html>
    32.1 --- a/javaquery/demo-calculator/pom.xml	Fri Jan 11 16:07:55 2013 +0100
    32.2 +++ b/javaquery/demo-calculator/pom.xml	Fri Jan 11 16:36:28 2013 +0100
    32.3 @@ -4,11 +4,11 @@
    32.4    <modelVersion>4.0.0</modelVersion>
    32.5  
    32.6    <groupId>org.apidesign.bck2brwsr</groupId>
    32.7 -  <artifactId>demo.calculator</artifactId>
    32.8 +  <artifactId>demo.static.calculator</artifactId>
    32.9    <version>0.3-SNAPSHOT</version>
   32.10    <packaging>jar</packaging>
   32.11  
   32.12 -  <name>JavaQuery Demo - Calculator</name>
   32.13 +  <name>JavaQuery Demo - Calculator - Static Compilation</name>
   32.14    <url>http://maven.apache.org</url>
   32.15  
   32.16    <properties>
    33.1 --- a/javaquery/pom.xml	Fri Jan 11 16:07:55 2013 +0100
    33.2 +++ b/javaquery/pom.xml	Fri Jan 11 16:36:28 2013 +0100
    33.3 @@ -14,5 +14,6 @@
    33.4      <modules>
    33.5          <module>api</module>
    33.6          <module>demo-calculator</module>
    33.7 +        <module>demo-calculator-dynamic</module>
    33.8      </modules>
    33.9  </project>
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/launcher/pom.xml	Fri Jan 11 16:36:28 2013 +0100
    34.3 @@ -0,0 +1,49 @@
    34.4 +<?xml version="1.0"?>
    34.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    34.6 +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    34.7 +  <modelVersion>4.0.0</modelVersion>
    34.8 +  <parent>
    34.9 +    <groupId>org.apidesign</groupId>
   34.10 +    <artifactId>bck2brwsr</artifactId>
   34.11 +    <version>0.3-SNAPSHOT</version>
   34.12 +  </parent>
   34.13 +  <groupId>org.apidesign.bck2brwsr</groupId>
   34.14 +  <artifactId>launcher</artifactId>
   34.15 +  <version>0.3-SNAPSHOT</version>
   34.16 +  <name>Bck2Brwsr Launcher</name>
   34.17 +  <url>http://maven.apache.org</url>
   34.18 +    <build>
   34.19 +        <plugins>
   34.20 +            <plugin>
   34.21 +                <groupId>org.apache.maven.plugins</groupId>
   34.22 +                <artifactId>maven-compiler-plugin</artifactId>
   34.23 +                <version>2.3.2</version>
   34.24 +                <configuration>
   34.25 +                    <source>1.7</source>
   34.26 +                    <target>1.7</target>
   34.27 +                </configuration>
   34.28 +            </plugin>
   34.29 +        </plugins>
   34.30 +    </build>
   34.31 +    <properties>
   34.32 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   34.33 +  </properties>
   34.34 +  <dependencies>
   34.35 +    <dependency>
   34.36 +      <groupId>junit</groupId>
   34.37 +      <artifactId>junit</artifactId>
   34.38 +      <version>3.8.1</version>
   34.39 +      <scope>test</scope>
   34.40 +    </dependency>
   34.41 +    <dependency>
   34.42 +      <groupId>org.glassfish.grizzly</groupId>
   34.43 +      <artifactId>grizzly-http-server</artifactId>
   34.44 +      <version>2.2.19</version>
   34.45 +    </dependency>
   34.46 +    <dependency>
   34.47 +      <groupId>${project.groupId}</groupId>
   34.48 +      <artifactId>vm4brwsr</artifactId>
   34.49 +      <version>${project.version}</version>
   34.50 +    </dependency>
   34.51 +  </dependencies>
   34.52 +</project>
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java	Fri Jan 11 16:36:28 2013 +0100
    35.3 @@ -0,0 +1,456 @@
    35.4 +/**
    35.5 + * Back 2 Browser Bytecode Translator
    35.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    35.7 + *
    35.8 + * This program is free software: you can redistribute it and/or modify
    35.9 + * it under the terms of the GNU General Public License as published by
   35.10 + * the Free Software Foundation, version 2 of the License.
   35.11 + *
   35.12 + * This program is distributed in the hope that it will be useful,
   35.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   35.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   35.15 + * GNU General Public License for more details.
   35.16 + *
   35.17 + * You should have received a copy of the GNU General Public License
   35.18 + * along with this program. Look for COPYING file in the top folder.
   35.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   35.20 + */
   35.21 +package org.apidesign.bck2brwsr.launcher;
   35.22 +
   35.23 +import java.io.Closeable;
   35.24 +import java.io.File;
   35.25 +import java.io.IOException;
   35.26 +import java.io.InputStream;
   35.27 +import java.io.InterruptedIOException;
   35.28 +import java.io.OutputStream;
   35.29 +import java.io.Writer;
   35.30 +import java.net.URI;
   35.31 +import java.net.URISyntaxException;
   35.32 +import java.net.URL;
   35.33 +import java.util.ArrayList;
   35.34 +import java.util.Arrays;
   35.35 +import java.util.Enumeration;
   35.36 +import java.util.LinkedHashSet;
   35.37 +import java.util.List;
   35.38 +import java.util.Set;
   35.39 +import java.util.concurrent.BlockingQueue;
   35.40 +import java.util.concurrent.CountDownLatch;
   35.41 +import java.util.concurrent.LinkedBlockingQueue;
   35.42 +import java.util.concurrent.TimeUnit;
   35.43 +import java.util.logging.Level;
   35.44 +import java.util.logging.Logger;
   35.45 +import org.apidesign.vm4brwsr.Bck2Brwsr;
   35.46 +import org.glassfish.grizzly.PortRange;
   35.47 +import org.glassfish.grizzly.http.server.HttpHandler;
   35.48 +import org.glassfish.grizzly.http.server.HttpServer;
   35.49 +import org.glassfish.grizzly.http.server.NetworkListener;
   35.50 +import org.glassfish.grizzly.http.server.Request;
   35.51 +import org.glassfish.grizzly.http.server.Response;
   35.52 +import org.glassfish.grizzly.http.server.ServerConfiguration;
   35.53 +
   35.54 +/**
   35.55 + * Lightweight server to launch Bck2Brwsr applications and tests.
   35.56 + * Supports execution in native browser as well as Java's internal 
   35.57 + * execution engine.
   35.58 + */
   35.59 +final class Bck2BrwsrLauncher extends Launcher implements Closeable {
   35.60 +    private static final Logger LOG = Logger.getLogger(Bck2BrwsrLauncher.class.getName());
   35.61 +    private static final MethodInvocation END = new MethodInvocation(null, null);
   35.62 +    private Set<ClassLoader> loaders = new LinkedHashSet<>();
   35.63 +    private BlockingQueue<MethodInvocation> methods = new LinkedBlockingQueue<>();
   35.64 +    private long timeOut;
   35.65 +    private final Res resources = new Res();
   35.66 +    private final String cmd;
   35.67 +    private Object[] brwsr;
   35.68 +    private HttpServer server;
   35.69 +    private CountDownLatch wait;
   35.70 +
   35.71 +    public Bck2BrwsrLauncher(String cmd) {
   35.72 +        this.cmd = cmd;
   35.73 +    }
   35.74 +    
   35.75 +    @Override
   35.76 +    public MethodInvocation addMethod(Class<?> clazz, String method) throws IOException {
   35.77 +        loaders.add(clazz.getClassLoader());
   35.78 +        MethodInvocation c = new MethodInvocation(clazz.getName(), method);
   35.79 +        methods.add(c);
   35.80 +        try {
   35.81 +            c.await(timeOut);
   35.82 +        } catch (InterruptedException ex) {
   35.83 +            throw new IOException(ex);
   35.84 +        }
   35.85 +        return c;
   35.86 +    }
   35.87 +    
   35.88 +    public void setTimeout(long ms) {
   35.89 +        timeOut = ms;
   35.90 +    }
   35.91 +    
   35.92 +    public void addClassLoader(ClassLoader url) {
   35.93 +        this.loaders.add(url);
   35.94 +    }
   35.95 +
   35.96 +    public void showURL(String startpage) throws IOException {
   35.97 +        if (!startpage.startsWith("/")) {
   35.98 +            startpage = "/" + startpage;
   35.99 +        }
  35.100 +        HttpServer s = initServer();
  35.101 +        s.getServerConfiguration().addHttpHandler(new Page(resources, null), "/");
  35.102 +        try {
  35.103 +            launchServerAndBrwsr(s, startpage);
  35.104 +        } catch (URISyntaxException | InterruptedException ex) {
  35.105 +            throw new IOException(ex);
  35.106 +        }
  35.107 +    }
  35.108 +
  35.109 +    @Override
  35.110 +    public void initialize() throws IOException {
  35.111 +        try {
  35.112 +            executeInBrowser();
  35.113 +        } catch (InterruptedException ex) {
  35.114 +            final InterruptedIOException iio = new InterruptedIOException(ex.getMessage());
  35.115 +            iio.initCause(ex);
  35.116 +            throw iio;
  35.117 +        } catch (Exception ex) {
  35.118 +            if (ex instanceof IOException) {
  35.119 +                throw (IOException)ex;
  35.120 +            }
  35.121 +            if (ex instanceof RuntimeException) {
  35.122 +                throw (RuntimeException)ex;
  35.123 +            }
  35.124 +            throw new IOException(ex);
  35.125 +        }
  35.126 +    }
  35.127 +    
  35.128 +    private HttpServer initServer() {
  35.129 +        HttpServer s = HttpServer.createSimpleServer(".", new PortRange(8080, 65535));
  35.130 +
  35.131 +        final ServerConfiguration conf = s.getServerConfiguration();
  35.132 +        conf.addHttpHandler(new Page(resources, 
  35.133 +            "org/apidesign/bck2brwsr/launcher/console.xhtml",
  35.134 +            "org.apidesign.bck2brwsr.launcher.Console", "welcome", "false"
  35.135 +        ), "/console");
  35.136 +        conf.addHttpHandler(new VM(resources), "/bck2brwsr.js");
  35.137 +        conf.addHttpHandler(new VMInit(), "/vm.js");
  35.138 +        conf.addHttpHandler(new Classes(resources), "/classes/");
  35.139 +        return s;
  35.140 +    }
  35.141 +    
  35.142 +    private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException {
  35.143 +        wait = new CountDownLatch(1);
  35.144 +        server = initServer();
  35.145 +        ServerConfiguration conf = server.getServerConfiguration();
  35.146 +        conf.addHttpHandler(new Page(resources, 
  35.147 +            "org/apidesign/bck2brwsr/launcher/harness.xhtml"
  35.148 +        ), "/execute");
  35.149 +        conf.addHttpHandler(new HttpHandler() {
  35.150 +            int cnt;
  35.151 +            List<MethodInvocation> cases = new ArrayList<>();
  35.152 +            @Override
  35.153 +            public void service(Request request, Response response) throws Exception {
  35.154 +                String id = request.getParameter("request");
  35.155 +                String value = request.getParameter("result");
  35.156 +                
  35.157 +                if (id != null && value != null) {
  35.158 +                    LOG.log(Level.INFO, "Received result for case {0} = {1}", new Object[]{id, value});
  35.159 +                    value = decodeURL(value);
  35.160 +                    cases.get(Integer.parseInt(id)).result(value, null);
  35.161 +                }
  35.162 +                
  35.163 +                MethodInvocation mi = methods.take();
  35.164 +                if (mi == END) {
  35.165 +                    response.getWriter().write("");
  35.166 +                    wait.countDown();
  35.167 +                    cnt = 0;
  35.168 +                    LOG.log(Level.INFO, "End of data reached. Exiting.");
  35.169 +                    return;
  35.170 +                }
  35.171 +                
  35.172 +                cases.add(mi);
  35.173 +                final String cn = mi.className;
  35.174 +                final String mn = mi.methodName;
  35.175 +                LOG.log(Level.INFO, "Request for {0} case. Sending {1}.{2}", new Object[]{cnt, cn, mn});
  35.176 +                response.getWriter().write("{"
  35.177 +                    + "className: '" + cn + "', "
  35.178 +                    + "methodName: '" + mn + "', "
  35.179 +                    + "request: " + cnt
  35.180 +                    + "}");
  35.181 +                cnt++;
  35.182 +            }
  35.183 +        }, "/data");
  35.184 +
  35.185 +        this.brwsr = launchServerAndBrwsr(server, "/execute");
  35.186 +    }
  35.187 +    
  35.188 +    @Override
  35.189 +    public void shutdown() throws IOException {
  35.190 +        methods.offer(END);
  35.191 +        for (;;) {
  35.192 +            int prev = methods.size();
  35.193 +            try {
  35.194 +                if (wait != null && wait.await(timeOut, TimeUnit.MILLISECONDS)) {
  35.195 +                    break;
  35.196 +                }
  35.197 +            } catch (InterruptedException ex) {
  35.198 +                throw new IOException(ex);
  35.199 +            }
  35.200 +            if (prev == methods.size()) {
  35.201 +                LOG.log(
  35.202 +                    Level.WARNING, 
  35.203 +                    "Timeout and no test has been executed meanwhile (at {0}). Giving up.", 
  35.204 +                    methods.size()
  35.205 +                );
  35.206 +                break;
  35.207 +            }
  35.208 +            LOG.log(Level.INFO, 
  35.209 +                "Timeout, but tests got from {0} to {1}. Trying again.", 
  35.210 +                new Object[]{prev, methods.size()}
  35.211 +            );
  35.212 +        }
  35.213 +        stopServerAndBrwsr(server, brwsr);
  35.214 +    }
  35.215 +    
  35.216 +    static void copyStream(InputStream is, OutputStream os, String baseURL, String... params) throws IOException {
  35.217 +        for (;;) {
  35.218 +            int ch = is.read();
  35.219 +            if (ch == -1) {
  35.220 +                break;
  35.221 +            }
  35.222 +            if (ch == '$') {
  35.223 +                int cnt = is.read() - '0';
  35.224 +                if (cnt == 'U' - '0') {
  35.225 +                    os.write(baseURL.getBytes());
  35.226 +                }
  35.227 +                if (cnt < params.length) {
  35.228 +                    os.write(params[cnt].getBytes());
  35.229 +                }
  35.230 +            } else {
  35.231 +                os.write(ch);
  35.232 +            }
  35.233 +        }
  35.234 +    }
  35.235 +
  35.236 +    private Object[] launchServerAndBrwsr(HttpServer server, final String page) throws IOException, URISyntaxException, InterruptedException {
  35.237 +        server.start();
  35.238 +        NetworkListener listener = server.getListeners().iterator().next();
  35.239 +        int port = listener.getPort();
  35.240 +        
  35.241 +        URI uri = new URI("http://localhost:" + port + page);
  35.242 +        LOG.log(Level.INFO, "Showing {0}", uri);
  35.243 +//        try {
  35.244 +//            Desktop.getDesktop().browse(uri);
  35.245 +//            return null;
  35.246 +//        } catch (UnsupportedOperationException ex)
  35.247 +        {
  35.248 +//            File dir = File.createTempFile("chrome", ".dir");
  35.249 +//            dir.delete();
  35.250 +//            dir.mkdirs();
  35.251 +//            String[] cmd = { 
  35.252 +//                "google-chrome", "--user-data-dir=" + dir, "--app=" + uri.toString()
  35.253 +//            };
  35.254 +//            LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmd));
  35.255 +//            final Process process = Runtime.getRuntime().exec(cmd);
  35.256 +//            return new Object[] { process, dir };
  35.257 +        }
  35.258 +        {
  35.259 +            String cmdName = cmd == null ? "xdg-open" : cmd;
  35.260 +            String[] cmdArr = { 
  35.261 +                cmdName, uri.toString()
  35.262 +            };
  35.263 +            LOG.log(Level.INFO, "Launching {0}", Arrays.toString(cmdArr));
  35.264 +            final Process process = Runtime.getRuntime().exec(cmdArr);
  35.265 +            return new Object[] { process, null };
  35.266 +        }
  35.267 +    }
  35.268 +    
  35.269 +    private static String decodeURL(String s) {
  35.270 +        for (;;) {
  35.271 +            int pos = s.indexOf('%');
  35.272 +            if (pos == -1) {
  35.273 +                return s;
  35.274 +            }
  35.275 +            int i = Integer.parseInt(s.substring(pos + 1, pos + 2), 16);
  35.276 +            s = s.substring(0, pos) + (char)i + s.substring(pos + 2);
  35.277 +        }
  35.278 +    }
  35.279 +    
  35.280 +    private void stopServerAndBrwsr(HttpServer server, Object[] brwsr) throws IOException {
  35.281 +        if (brwsr == null) {
  35.282 +            return;
  35.283 +        }
  35.284 +        Process process = (Process)brwsr[0];
  35.285 +        
  35.286 +        server.stop();
  35.287 +        InputStream stdout = process.getInputStream();
  35.288 +        InputStream stderr = process.getErrorStream();
  35.289 +        drain("StdOut", stdout);
  35.290 +        drain("StdErr", stderr);
  35.291 +        process.destroy();
  35.292 +        int res;
  35.293 +        try {
  35.294 +            res = process.waitFor();
  35.295 +        } catch (InterruptedException ex) {
  35.296 +            throw new IOException(ex);
  35.297 +        }
  35.298 +        LOG.log(Level.INFO, "Exit code: {0}", res);
  35.299 +
  35.300 +        deleteTree((File)brwsr[1]);
  35.301 +    }
  35.302 +    
  35.303 +    private static void drain(String name, InputStream is) throws IOException {
  35.304 +        int av = is.available();
  35.305 +        if (av > 0) {
  35.306 +            StringBuilder sb = new StringBuilder();
  35.307 +            sb.append("v== ").append(name).append(" ==v\n");
  35.308 +            while (av-- > 0) {
  35.309 +                sb.append((char)is.read());
  35.310 +            }
  35.311 +            sb.append("\n^== ").append(name).append(" ==^");
  35.312 +            LOG.log(Level.INFO, sb.toString());
  35.313 +        }
  35.314 +    }
  35.315 +
  35.316 +    private void deleteTree(File file) {
  35.317 +        if (file == null) {
  35.318 +            return;
  35.319 +        }
  35.320 +        File[] arr = file.listFiles();
  35.321 +        if (arr != null) {
  35.322 +            for (File s : arr) {
  35.323 +                deleteTree(s);
  35.324 +            }
  35.325 +        }
  35.326 +        file.delete();
  35.327 +    }
  35.328 +
  35.329 +    @Override
  35.330 +    public void close() throws IOException {
  35.331 +        shutdown();
  35.332 +    }
  35.333 +
  35.334 +    private class Res implements Bck2Brwsr.Resources {
  35.335 +        @Override
  35.336 +        public InputStream get(String resource) throws IOException {
  35.337 +            for (ClassLoader l : loaders) {
  35.338 +                URL u = null;
  35.339 +                Enumeration<URL> en = l.getResources(resource);
  35.340 +                while (en.hasMoreElements()) {
  35.341 +                    u = en.nextElement();
  35.342 +                }
  35.343 +                if (u != null) {
  35.344 +                    return u.openStream();
  35.345 +                }
  35.346 +            }
  35.347 +            throw new IOException("Can't find " + resource);
  35.348 +        }
  35.349 +    }
  35.350 +
  35.351 +    private static class Page extends HttpHandler {
  35.352 +        private final String resource;
  35.353 +        private final String[] args;
  35.354 +        private final Res res;
  35.355 +        
  35.356 +        public Page(Res res, String resource, String... args) {
  35.357 +            this.res = res;
  35.358 +            this.resource = resource;
  35.359 +            this.args = args;
  35.360 +        }
  35.361 +
  35.362 +        @Override
  35.363 +        public void service(Request request, Response response) throws Exception {
  35.364 +            String r = resource;
  35.365 +            if (r == null) {
  35.366 +                r = request.getHttpHandlerPath();
  35.367 +                if (r.startsWith("/")) {
  35.368 +                    r = r.substring(1);
  35.369 +                }
  35.370 +            }
  35.371 +            if (r.endsWith(".html") || r.endsWith(".xhtml")) {
  35.372 +                response.setContentType("text/html");
  35.373 +            }
  35.374 +            OutputStream os = response.getOutputStream();
  35.375 +            try (InputStream is = res.get(r)) {
  35.376 +                copyStream(is, os, request.getRequestURL().toString(), args);
  35.377 +            } catch (IOException ex) {
  35.378 +                response.setDetailMessage(ex.getLocalizedMessage());
  35.379 +                response.setError();
  35.380 +                response.setStatus(404);
  35.381 +            }
  35.382 +        }
  35.383 +    }
  35.384 +
  35.385 +    private static class VM extends HttpHandler {
  35.386 +        private final Res loader;
  35.387 +
  35.388 +        public VM(Res loader) {
  35.389 +            this.loader = loader;
  35.390 +        }
  35.391 +
  35.392 +        @Override
  35.393 +        public void service(Request request, Response response) throws Exception {
  35.394 +            response.setCharacterEncoding("UTF-8");
  35.395 +            response.setContentType("text/javascript");
  35.396 +            Bck2Brwsr.generate(response.getWriter(), loader);
  35.397 +        }
  35.398 +    }
  35.399 +    private static class VMInit extends HttpHandler {
  35.400 +        public VMInit() {
  35.401 +        }
  35.402 +
  35.403 +        @Override
  35.404 +        public void service(Request request, Response response) throws Exception {
  35.405 +            response.setCharacterEncoding("UTF-8");
  35.406 +            response.setContentType("text/javascript");
  35.407 +            response.getWriter().append(
  35.408 +                "function ldCls(res) {\n"
  35.409 +                + "  var request = new XMLHttpRequest();\n"
  35.410 +                + "  request.open('GET', '/classes/' + res, false);\n"
  35.411 +                + "  request.send();\n"
  35.412 +                + "  var arr = eval('(' + request.responseText + ')');\n"
  35.413 +                + "  return arr;\n"
  35.414 +                + "}\n"
  35.415 +                + "var vm = new bck2brwsr(ldCls);\n");
  35.416 +        }
  35.417 +    }
  35.418 +
  35.419 +    private static class Classes extends HttpHandler {
  35.420 +        private final Res loader;
  35.421 +
  35.422 +        public Classes(Res loader) {
  35.423 +            this.loader = loader;
  35.424 +        }
  35.425 +
  35.426 +        @Override
  35.427 +        public void service(Request request, Response response) throws Exception {
  35.428 +            String res = request.getHttpHandlerPath();
  35.429 +            if (res.startsWith("/")) {
  35.430 +                res = res.substring(1);
  35.431 +            }
  35.432 +            try (InputStream is = loader.get(res)) {
  35.433 +                response.setContentType("text/javascript");
  35.434 +                Writer w = response.getWriter();
  35.435 +                w.append("[");
  35.436 +                for (int i = 0;; i++) {
  35.437 +                    int b = is.read();
  35.438 +                    if (b == -1) {
  35.439 +                        break;
  35.440 +                    }
  35.441 +                    if (i > 0) {
  35.442 +                        w.append(", ");
  35.443 +                    }
  35.444 +                    if (i % 20 == 0) {
  35.445 +                        w.write("\n");
  35.446 +                    }
  35.447 +                    if (b > 127) {
  35.448 +                        b = b - 256;
  35.449 +                    }
  35.450 +                    w.append(Integer.toString(b));
  35.451 +                }
  35.452 +                w.append("\n]");
  35.453 +            } catch (IOException ex) {
  35.454 +                response.setError();
  35.455 +                response.setDetailMessage(ex.getMessage());
  35.456 +            }
  35.457 +        }
  35.458 +    }
  35.459 +}
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Console.java	Fri Jan 11 16:36:28 2013 +0100
    36.3 @@ -0,0 +1,208 @@
    36.4 +/**
    36.5 + * Back 2 Browser Bytecode Translator
    36.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    36.7 + *
    36.8 + * This program is free software: you can redistribute it and/or modify
    36.9 + * it under the terms of the GNU General Public License as published by
   36.10 + * the Free Software Foundation, version 2 of the License.
   36.11 + *
   36.12 + * This program is distributed in the hope that it will be useful,
   36.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   36.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   36.15 + * GNU General Public License for more details.
   36.16 + *
   36.17 + * You should have received a copy of the GNU General Public License
   36.18 + * along with this program. Look for COPYING file in the top folder.
   36.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   36.20 + */
   36.21 +package org.apidesign.bck2brwsr.launcher;
   36.22 +
   36.23 +import java.io.IOException;
   36.24 +import java.io.InputStream;
   36.25 +import java.lang.reflect.InvocationTargetException;
   36.26 +import java.lang.reflect.Method;
   36.27 +import java.lang.reflect.Modifier;
   36.28 +import java.net.URL;
   36.29 +import java.util.Enumeration;
   36.30 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   36.31 +
   36.32 +/**
   36.33 + *
   36.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   36.35 + */
   36.36 +public class Console {
   36.37 +    public static String welcome() {
   36.38 +        return "HellofromBck2Brwsr";
   36.39 +    }
   36.40 +    public static String multiply() {
   36.41 +        return String.valueOf(Integer.MAX_VALUE / 2 + Integer.MAX_VALUE);
   36.42 +    }
   36.43 +    
   36.44 +    @JavaScriptBody(args = {"id", "attr"}, body = 
   36.45 +        "return window.document.getElementById(id)[attr].toString();")
   36.46 +    private static native Object getAttr(String id, String attr);
   36.47 +
   36.48 +    @JavaScriptBody(args = {"id", "attr", "value"}, body = 
   36.49 +        "window.document.getElementById(id)[attr] = value;")
   36.50 +    private static native void setAttr(String id, String attr, Object value);
   36.51 +    
   36.52 +    @JavaScriptBody(args = {}, body = "return; window.close();")
   36.53 +    private static native void closeWindow();
   36.54 +
   36.55 +    private static void log(String newText) {
   36.56 +        String id = "result";
   36.57 +        String attr = "value";
   36.58 +        setAttr(id, attr, getAttr(id, attr) + "\n" + newText);
   36.59 +        setAttr(id, "scrollTop", getAttr(id, "scrollHeight"));
   36.60 +    }
   36.61 +    
   36.62 +    public static void execute() throws Exception {
   36.63 +        String clazz = (String) getAttr("clazz", "value");
   36.64 +        String method = (String) getAttr("method", "value");
   36.65 +        Object res = invokeMethod(clazz, method);
   36.66 +        setAttr("result", "value", res);
   36.67 +    }
   36.68 +    
   36.69 +    public static void harness(String url) {
   36.70 +        log("Connecting to " + url);
   36.71 +        try {
   36.72 +            URL u = new URL(url);
   36.73 +            for (;;) {
   36.74 +                String data = (String) u.getContent(new Class[] { String.class });
   36.75 +                log("\nGot \"" + data + "\"");
   36.76 +                if (data.isEmpty()) {
   36.77 +                    log("No data, exiting");
   36.78 +                    closeWindow();
   36.79 +                    break;
   36.80 +                }
   36.81 +                
   36.82 +                Case c = Case.parseData(data);
   36.83 +                log("Invoking " + c.getClassName() + '.' + c.getMethodName() + " as request: " + c.getRequestId());
   36.84 +
   36.85 +                Object result = invokeMethod(c.getClassName(), c.getMethodName());
   36.86 +                
   36.87 +                log("Result: " + result);
   36.88 +                
   36.89 +                result = encodeURL("" + result);
   36.90 +                
   36.91 +                log("Sending back: " + url + "?request=" + c.getRequestId() + "&result=" + result);
   36.92 +                u = new URL(url + "?request=" + c.getRequestId() + "&result=" + result);
   36.93 +            }
   36.94 +            
   36.95 +            
   36.96 +        } catch (Exception ex) {
   36.97 +            log(ex.getMessage());
   36.98 +        }
   36.99 +    }
  36.100 +    
  36.101 +    private static String encodeURL(String r) {
  36.102 +        StringBuilder sb = new StringBuilder();
  36.103 +        for (int i = 0; i < r.length(); i++) {
  36.104 +            int ch = r.charAt(i);
  36.105 +            if (ch < 32 || ch == '%' || ch == '+') {
  36.106 +                sb.append("%").append(("0" + Integer.toHexString(ch)).substring(0, 2));
  36.107 +            } else {
  36.108 +                if (ch == 32) {
  36.109 +                    sb.append("+");
  36.110 +                } else {
  36.111 +                    sb.append((char)ch);
  36.112 +                }
  36.113 +            }
  36.114 +        }
  36.115 +        return sb.toString();
  36.116 +    }
  36.117 +    
  36.118 +    static String invoke(String clazz, String method) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException {
  36.119 +        final Object r = invokeMethod(clazz, method);
  36.120 +        return r == null ? "null" : r.toString().toString();
  36.121 +    }
  36.122 +
  36.123 +    /** Helper method that inspects the classpath and loads given resource
  36.124 +     * (usually a class file). Used while running tests in Rhino.
  36.125 +     * 
  36.126 +     * @param name resource name to find
  36.127 +     * @return the array of bytes in the given resource
  36.128 +     * @throws IOException I/O in case something goes wrong
  36.129 +     */
  36.130 +    public static byte[] read(String name) throws IOException {
  36.131 +        URL u = null;
  36.132 +        Enumeration<URL> en = Console.class.getClassLoader().getResources(name);
  36.133 +        while (en.hasMoreElements()) {
  36.134 +            u = en.nextElement();
  36.135 +        }
  36.136 +        if (u == null) {
  36.137 +            throw new IOException("Can't find " + name);
  36.138 +        }
  36.139 +        try (InputStream is = u.openStream()) {
  36.140 +            byte[] arr;
  36.141 +            arr = new byte[is.available()];
  36.142 +            int offset = 0;
  36.143 +            while (offset < arr.length) {
  36.144 +                int len = is.read(arr, offset, arr.length - offset);
  36.145 +                if (len == -1) {
  36.146 +                    throw new IOException("Can't read " + name);
  36.147 +                }
  36.148 +                offset += len;
  36.149 +            }
  36.150 +            return arr;
  36.151 +        }
  36.152 +    }
  36.153 +   
  36.154 +    private static Object invokeMethod(String clazz, String method) 
  36.155 +    throws ClassNotFoundException, InvocationTargetException, 
  36.156 +    SecurityException, IllegalAccessException, IllegalArgumentException,
  36.157 +    InstantiationException {
  36.158 +        Method found = null;
  36.159 +        Class<?> c = Class.forName(clazz);
  36.160 +        for (Method m : c.getMethods()) {
  36.161 +            if (m.getName().equals(method)) {
  36.162 +                found = m;
  36.163 +            }
  36.164 +        }
  36.165 +        Object res;
  36.166 +        if (found != null) {
  36.167 +            try {
  36.168 +                if ((found.getModifiers() & Modifier.STATIC) != 0) {
  36.169 +                    res = found.invoke(null);
  36.170 +                } else {
  36.171 +                    res = found.invoke(c.newInstance());
  36.172 +                }
  36.173 +            } catch (Exception ex) {
  36.174 +                res = ex.getClass().getName() + ":" + ex.getMessage();
  36.175 +            }
  36.176 +        } else {
  36.177 +            res = "Can't find method " + method + " in " + clazz;
  36.178 +        }
  36.179 +        return res;
  36.180 +    }
  36.181 +    
  36.182 +    private static final class Case {
  36.183 +        private final Object data;
  36.184 +
  36.185 +        private Case(Object data) {
  36.186 +            this.data = data;
  36.187 +        }
  36.188 +        
  36.189 +        public static Case parseData(String s) {
  36.190 +            return new Case(toJSON(s));
  36.191 +        }
  36.192 +        
  36.193 +        public String getMethodName() {
  36.194 +            return value("methodName", data);
  36.195 +        }
  36.196 +
  36.197 +        public String getClassName() {
  36.198 +            return value("className", data);
  36.199 +        }
  36.200 +        
  36.201 +        public String getRequestId() {
  36.202 +            return value("request", data);
  36.203 +        }
  36.204 +        
  36.205 +        @JavaScriptBody(args = "s", body = "return eval('(' + s + ')');")
  36.206 +        private static native Object toJSON(String s);
  36.207 +        
  36.208 +        @JavaScriptBody(args = {"p", "d"}, body = "return d[p].toString();")
  36.209 +        private static native String value(String p, Object d);
  36.210 +    }
  36.211 +}
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/JSLauncher.java	Fri Jan 11 16:36:28 2013 +0100
    37.3 @@ -0,0 +1,127 @@
    37.4 +/**
    37.5 + * Back 2 Browser Bytecode Translator
    37.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    37.7 + *
    37.8 + * This program is free software: you can redistribute it and/or modify
    37.9 + * it under the terms of the GNU General Public License as published by
   37.10 + * the Free Software Foundation, version 2 of the License.
   37.11 + *
   37.12 + * This program is distributed in the hope that it will be useful,
   37.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   37.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   37.15 + * GNU General Public License for more details.
   37.16 + *
   37.17 + * You should have received a copy of the GNU General Public License
   37.18 + * along with this program. Look for COPYING file in the top folder.
   37.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   37.20 + */
   37.21 +package org.apidesign.bck2brwsr.launcher;
   37.22 +
   37.23 +import java.io.IOException;
   37.24 +import java.io.InputStream;
   37.25 +import java.net.URL;
   37.26 +import java.util.Enumeration;
   37.27 +import java.util.LinkedHashSet;
   37.28 +import java.util.Set;
   37.29 +import java.util.logging.Logger;
   37.30 +import javax.script.Invocable;
   37.31 +import javax.script.ScriptEngine;
   37.32 +import javax.script.ScriptEngineManager;
   37.33 +import javax.script.ScriptException;
   37.34 +import org.apidesign.vm4brwsr.Bck2Brwsr;
   37.35 +
   37.36 +/**
   37.37 + * Tests execution in Java's internal scripting engine.
   37.38 + */
   37.39 +final class JSLauncher extends Launcher {
   37.40 +    private static final Logger LOG = Logger.getLogger(JSLauncher.class.getName());
   37.41 +    private Set<ClassLoader> loaders = new LinkedHashSet<>();
   37.42 +    private final Res resources = new Res();
   37.43 +    private Invocable code;
   37.44 +    private StringBuilder codeSeq;
   37.45 +    private Object console;
   37.46 +    
   37.47 +    
   37.48 +    @Override
   37.49 +    public MethodInvocation addMethod(Class<?> clazz, String method) {
   37.50 +        loaders.add(clazz.getClassLoader());
   37.51 +        MethodInvocation mi = new MethodInvocation(clazz.getName(), method);
   37.52 +        try {
   37.53 +            mi.result(code.invokeMethod(
   37.54 +                console,
   37.55 +                "invoke__Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2",
   37.56 +                mi.className, mi.methodName).toString(), null);
   37.57 +        } catch (ScriptException | NoSuchMethodException ex) {
   37.58 +            mi.result(null, ex);
   37.59 +        }
   37.60 +        return mi;
   37.61 +    }
   37.62 +    
   37.63 +    public void addClassLoader(ClassLoader url) {
   37.64 +        this.loaders.add(url);
   37.65 +    }
   37.66 +
   37.67 +    @Override
   37.68 +    public void initialize() throws IOException {
   37.69 +        try {
   37.70 +            initRhino();
   37.71 +        } catch (Exception ex) {
   37.72 +            if (ex instanceof IOException) {
   37.73 +                throw (IOException)ex;
   37.74 +            }
   37.75 +            if (ex instanceof RuntimeException) {
   37.76 +                throw (RuntimeException)ex;
   37.77 +            }
   37.78 +            throw new IOException(ex);
   37.79 +        }
   37.80 +    }
   37.81 +    
   37.82 +    private void initRhino() throws IOException, ScriptException, NoSuchMethodException {
   37.83 +        StringBuilder sb = new StringBuilder();
   37.84 +        Bck2Brwsr.generate(sb, new Res());
   37.85 +
   37.86 +        ScriptEngineManager sem = new ScriptEngineManager();
   37.87 +        ScriptEngine mach = sem.getEngineByExtension("js");
   37.88 +
   37.89 +        sb.append(
   37.90 +              "\nvar vm = new bck2brwsr(org.apidesign.bck2brwsr.launcher.Console.read);"
   37.91 +            + "\nfunction initVM() { return vm; };"
   37.92 +            + "\n");
   37.93 +
   37.94 +        Object res = mach.eval(sb.toString());
   37.95 +        if (!(mach instanceof Invocable)) {
   37.96 +            throw new IOException("It is invocable object: " + res);
   37.97 +        }
   37.98 +        code = (Invocable) mach;
   37.99 +        codeSeq = sb;
  37.100 +        
  37.101 +        Object vm = code.invokeFunction("initVM");
  37.102 +        console = code.invokeMethod(vm, "loadClass", Console.class.getName());
  37.103 +    }
  37.104 +
  37.105 +    @Override
  37.106 +    public void shutdown() throws IOException {
  37.107 +    }
  37.108 +
  37.109 +    @Override
  37.110 +    public String toString() {
  37.111 +        return codeSeq.toString();
  37.112 +    }
  37.113 +    
  37.114 +    private class Res implements Bck2Brwsr.Resources {
  37.115 +        @Override
  37.116 +        public InputStream get(String resource) throws IOException {
  37.117 +            for (ClassLoader l : loaders) {
  37.118 +                URL u = null;
  37.119 +                Enumeration<URL> en = l.getResources(resource);
  37.120 +                while (en.hasMoreElements()) {
  37.121 +                    u = en.nextElement();
  37.122 +                }
  37.123 +                if (u != null) {
  37.124 +                    return u.openStream();
  37.125 +                }
  37.126 +            }
  37.127 +            throw new IOException("Can't find " + resource);
  37.128 +        }
  37.129 +    }
  37.130 +}
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Launcher.java	Fri Jan 11 16:36:28 2013 +0100
    38.3 @@ -0,0 +1,63 @@
    38.4 +/**
    38.5 + * Back 2 Browser Bytecode Translator
    38.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    38.7 + *
    38.8 + * This program is free software: you can redistribute it and/or modify
    38.9 + * it under the terms of the GNU General Public License as published by
   38.10 + * the Free Software Foundation, version 2 of the License.
   38.11 + *
   38.12 + * This program is distributed in the hope that it will be useful,
   38.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   38.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   38.15 + * GNU General Public License for more details.
   38.16 + *
   38.17 + * You should have received a copy of the GNU General Public License
   38.18 + * along with this program. Look for COPYING file in the top folder.
   38.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   38.20 + */
   38.21 +package org.apidesign.bck2brwsr.launcher;
   38.22 +
   38.23 +import java.io.Closeable;
   38.24 +import java.io.IOException;
   38.25 +import java.net.URLClassLoader;
   38.26 +import org.apidesign.vm4brwsr.Bck2Brwsr;
   38.27 +
   38.28 +/** An abstraction for executing tests in a Bck2Brwsr virtual machine.
   38.29 + * Either in JavaScript engine, or in external browser.
   38.30 + *
   38.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   38.32 + */
   38.33 +public abstract class Launcher {
   38.34 +
   38.35 +    Launcher() {
   38.36 +    }
   38.37 +    
   38.38 +    abstract MethodInvocation addMethod(Class<?> clazz, String method) throws IOException; 
   38.39 +
   38.40 +    public abstract void initialize() throws IOException;
   38.41 +    public abstract void shutdown() throws IOException;
   38.42 +    public MethodInvocation invokeMethod(Class<?> clazz, String method) throws IOException {
   38.43 +        return addMethod(clazz, method);
   38.44 +    }
   38.45 +    
   38.46 +    
   38.47 +
   38.48 +    public static Launcher createJavaScript() {
   38.49 +        final JSLauncher l = new JSLauncher();
   38.50 +        l.addClassLoader(Bck2Brwsr.class.getClassLoader());
   38.51 +        return l;
   38.52 +    }
   38.53 +    
   38.54 +    public static Launcher createBrowser(String cmd) {
   38.55 +        final Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(cmd);
   38.56 +        l.addClassLoader(Bck2Brwsr.class.getClassLoader());
   38.57 +        l.setTimeout(180000);
   38.58 +        return l;
   38.59 +    }
   38.60 +    public static Closeable showURL(URLClassLoader classes, String startpage) throws IOException {
   38.61 +        Bck2BrwsrLauncher l = new Bck2BrwsrLauncher(null);
   38.62 +        l.addClassLoader(classes);
   38.63 +        l.showURL(startpage);
   38.64 +        return l;
   38.65 +    }
   38.66 +}
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/MethodInvocation.java	Fri Jan 11 16:36:28 2013 +0100
    39.3 @@ -0,0 +1,57 @@
    39.4 +/**
    39.5 + * Back 2 Browser Bytecode Translator
    39.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    39.7 + *
    39.8 + * This program is free software: you can redistribute it and/or modify
    39.9 + * it under the terms of the GNU General Public License as published by
   39.10 + * the Free Software Foundation, version 2 of the License.
   39.11 + *
   39.12 + * This program is distributed in the hope that it will be useful,
   39.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   39.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   39.15 + * GNU General Public License for more details.
   39.16 + *
   39.17 + * You should have received a copy of the GNU General Public License
   39.18 + * along with this program. Look for COPYING file in the top folder.
   39.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   39.20 + */
   39.21 +package org.apidesign.bck2brwsr.launcher;
   39.22 +
   39.23 +import java.util.concurrent.CountDownLatch;
   39.24 +import java.util.concurrent.TimeUnit;
   39.25 +
   39.26 +/**
   39.27 + *
   39.28 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   39.29 + */
   39.30 +public final class MethodInvocation {
   39.31 +    final CountDownLatch wait = new CountDownLatch(1);
   39.32 +    final String className;
   39.33 +    final String methodName;
   39.34 +    private String result;
   39.35 +    private Throwable exception;
   39.36 +
   39.37 +    MethodInvocation(String className, String methodName) {
   39.38 +        this.className = className;
   39.39 +        this.methodName = methodName;
   39.40 +    }
   39.41 +    
   39.42 +    void await(long timeOut) throws InterruptedException {
   39.43 +        wait.await(timeOut, TimeUnit.MILLISECONDS);
   39.44 +    }
   39.45 +    
   39.46 +    void result(String r, Throwable e) {
   39.47 +        this.result = r;
   39.48 +        this.exception = e;
   39.49 +        wait.countDown();
   39.50 +    }
   39.51 +
   39.52 +    @Override
   39.53 +    public String toString() {
   39.54 +        if (exception != null) {
   39.55 +            return exception.toString();
   39.56 +        }
   39.57 +        return result;
   39.58 +    }
   39.59 +    
   39.60 +}
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/console.xhtml	Fri Jan 11 16:36:28 2013 +0100
    40.3 @@ -0,0 +1,52 @@
    40.4 +<?xml version="1.0" encoding="UTF-8"?>
    40.5 +<!--
    40.6 +
    40.7 +    Back 2 Browser Bytecode Translator
    40.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    40.9 +
   40.10 +    This program is free software: you can redistribute it and/or modify
   40.11 +    it under the terms of the GNU General Public License as published by
   40.12 +    the Free Software Foundation, version 2 of the License.
   40.13 +
   40.14 +    This program is distributed in the hope that it will be useful,
   40.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   40.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   40.17 +    GNU General Public License for more details.
   40.18 +
   40.19 +    You should have received a copy of the GNU General Public License
   40.20 +    along with this program. Look for COPYING file in the top folder.
   40.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   40.22 +
   40.23 +-->
   40.24 +<!DOCTYPE html>
   40.25 +<html xmlns="http://www.w3.org/1999/xhtml">
   40.26 +    <head>
   40.27 +        <title>Bck2Brwsr Launcher</title>
   40.28 +    </head>
   40.29 +    <body>
   40.30 +        <script src="/bck2brwsr.js"></script>
   40.31 +        <script src="/vm.js"></script>
   40.32 +        
   40.33 +        <h1>Bck2Browser Console Launcher</h1>
   40.34 +        
   40.35 +        Class Name:
   40.36 +        <input id="clazz" value="$0"/>
   40.37 +        <br/>
   40.38 +        Method Name:
   40.39 +
   40.40 +        <input id="method" value="$1"/>
   40.41 +        <br/>
   40.42 +        
   40.43 +        <button onclick="vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').execute__V();">Execute!</button>
   40.44 +        
   40.45 +        <hr/>
   40.46 +        <textarea id="result" rows="10" cols="80" disabled="">
   40.47 +        </textarea>
   40.48 +        
   40.49 +        <script type="text/javascript">
   40.50 +            if ($2) {
   40.51 +                vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').execute__V();
   40.52 +            }
   40.53 +        </script>
   40.54 +    </body>
   40.55 +</html>
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/launcher/src/main/resources/org/apidesign/bck2brwsr/launcher/harness.xhtml	Fri Jan 11 16:36:28 2013 +0100
    41.3 @@ -0,0 +1,39 @@
    41.4 +<?xml version="1.0" encoding="UTF-8"?>
    41.5 +<!--
    41.6 +
    41.7 +    Back 2 Browser Bytecode Translator
    41.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    41.9 +
   41.10 +    This program is free software: you can redistribute it and/or modify
   41.11 +    it under the terms of the GNU General Public License as published by
   41.12 +    the Free Software Foundation, version 2 of the License.
   41.13 +
   41.14 +    This program is distributed in the hope that it will be useful,
   41.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   41.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   41.17 +    GNU General Public License for more details.
   41.18 +
   41.19 +    You should have received a copy of the GNU General Public License
   41.20 +    along with this program. Look for COPYING file in the top folder.
   41.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   41.22 +
   41.23 +-->
   41.24 +<!DOCTYPE html>
   41.25 +<html xmlns="http://www.w3.org/1999/xhtml">
   41.26 +    <head>
   41.27 +        <title>Bck2Brwsr Harness</title>
   41.28 +    </head>
   41.29 +    <body>
   41.30 +        <script src="/bck2brwsr.js"></script>
   41.31 +        <script src="/vm.js"></script>
   41.32 +        
   41.33 +        <h1>Bck2Browser Execution Harness</h1>
   41.34 +        
   41.35 +        <textarea id="result" rows="25" style="width: 100%;" disabled="">
   41.36 +        </textarea>
   41.37 +        
   41.38 +        <script type="text/javascript">
   41.39 +            vm.loadClass('org.apidesign.bck2brwsr.launcher.Console').harness__VLjava_lang_String_2('$U/../data');
   41.40 +        </script>
   41.41 +    </body>
   41.42 +</html>
    42.1 --- a/mojo/pom.xml	Fri Jan 11 16:07:55 2013 +0100
    42.2 +++ b/mojo/pom.xml	Fri Jan 11 16:36:28 2013 +0100
    42.3 @@ -11,7 +11,7 @@
    42.4    <artifactId>mojo</artifactId>
    42.5    <version>0.3-SNAPSHOT</version>
    42.6    <packaging>maven-plugin</packaging>
    42.7 -  <name>Maven Mojo to Compile to JavaScript</name>
    42.8 +  <name>Bck2Brwsr Maven Project</name>
    42.9    <url>http://maven.apache.org</url>
   42.10        <build>
   42.11          <plugins>
   42.12 @@ -77,5 +77,10 @@
   42.13        <version>3.0.2</version>
   42.14        <type>jar</type>
   42.15      </dependency>
   42.16 +    <dependency>
   42.17 +        <groupId>${project.groupId}</groupId>
   42.18 +        <artifactId>launcher</artifactId>
   42.19 +      <version>${project.version}</version>
   42.20 +    </dependency>
   42.21  </dependencies>
   42.22  </project>
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/mojo/src/main/java/org/apidesign/bck2brwsr/mojo/BrswrMojo.java	Fri Jan 11 16:36:28 2013 +0100
    43.3 @@ -0,0 +1,89 @@
    43.4 +/**
    43.5 + * Back 2 Browser Bytecode Translator
    43.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    43.7 + *
    43.8 + * This program is free software: you can redistribute it and/or modify
    43.9 + * it under the terms of the GNU General Public License as published by
   43.10 + * the Free Software Foundation, version 2 of the License.
   43.11 + *
   43.12 + * This program is distributed in the hope that it will be useful,
   43.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   43.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   43.15 + * GNU General Public License for more details.
   43.16 + *
   43.17 + * You should have received a copy of the GNU General Public License
   43.18 + * along with this program. Look for COPYING file in the top folder.
   43.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   43.20 + */
   43.21 +package org.apidesign.bck2brwsr.mojo;
   43.22 +
   43.23 +import java.io.Closeable;
   43.24 +import org.apache.maven.plugin.AbstractMojo;
   43.25 +
   43.26 +import java.io.File;
   43.27 +import java.io.IOException;
   43.28 +import java.net.MalformedURLException;
   43.29 +import java.net.URL;
   43.30 +import java.net.URLClassLoader;
   43.31 +import java.util.ArrayList;
   43.32 +import java.util.Collection;
   43.33 +import java.util.List;
   43.34 +import org.apache.maven.artifact.Artifact;
   43.35 +import org.apache.maven.plugin.MojoExecutionException;
   43.36 +import org.apache.maven.plugins.annotations.LifecyclePhase;
   43.37 +import org.apache.maven.plugins.annotations.Mojo;
   43.38 +import org.apache.maven.plugins.annotations.Parameter;
   43.39 +import org.apache.maven.project.MavenProject;
   43.40 +import org.apidesign.bck2brwsr.launcher.Launcher;
   43.41 +
   43.42 +/** Executes given HTML page in a browser. */
   43.43 +@Mojo(name="brwsr", defaultPhase=LifecyclePhase.DEPLOY)
   43.44 +public class BrswrMojo extends AbstractMojo {
   43.45 +    public BrswrMojo() {
   43.46 +    }
   43.47 +    /** Resource to show as initial page */
   43.48 +    @Parameter
   43.49 +    private String startpage;
   43.50 +
   43.51 +    @Parameter(defaultValue="${project}")
   43.52 +    private MavenProject prj;
   43.53 +    
   43.54 +    /** Root of the class files */
   43.55 +    @Parameter(defaultValue="${project.build.directory}/classes")
   43.56 +    private File classes;
   43.57 +
   43.58 +    @Override
   43.59 +    public void execute() throws MojoExecutionException {
   43.60 +        if (startpage == null) {
   43.61 +            throw new MojoExecutionException("You have to provide a start page");
   43.62 +        }
   43.63 +
   43.64 +        try {
   43.65 +            URLClassLoader url = buildClassLoader(classes, prj.getDependencyArtifacts());
   43.66 +            
   43.67 +            Closeable httpServer;
   43.68 +            try {
   43.69 +                httpServer = Launcher.showURL(url, startpage());
   43.70 +            } catch (Exception ex) {
   43.71 +                throw new MojoExecutionException("Can't open " + startpage(), ex);
   43.72 +            }
   43.73 +            System.in.read();
   43.74 +            httpServer.close();
   43.75 +        } catch (IOException ex) {
   43.76 +            throw new MojoExecutionException("Can't show the browser", ex);
   43.77 +        }
   43.78 +    }
   43.79 +    
   43.80 +    private String startpage() {
   43.81 +        return startpage;
   43.82 +    }
   43.83 +
   43.84 +    private static URLClassLoader buildClassLoader(File root, Collection<Artifact> deps) throws MalformedURLException {
   43.85 +        List<URL> arr = new ArrayList<URL>();
   43.86 +        arr.add(root.toURI().toURL());
   43.87 +        for (Artifact a : deps) {
   43.88 +            arr.add(a.getFile().toURI().toURL());
   43.89 +        }
   43.90 +        return new URLClassLoader(arr.toArray(new URL[0]), BrswrMojo.class.getClassLoader());
   43.91 +    }
   43.92 +}
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/mojo/src/main/resources/META-INF/maven/archetype-metadata.xml	Fri Jan 11 16:36:28 2013 +0100
    44.3 @@ -0,0 +1,42 @@
    44.4 +<?xml version="1.0" encoding="UTF-8"?>
    44.5 +<!--
    44.6 +
    44.7 +    Back 2 Browser Bytecode Translator
    44.8 +    Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    44.9 +
   44.10 +    This program is free software: you can redistribute it and/or modify
   44.11 +    it under the terms of the GNU General Public License as published by
   44.12 +    the Free Software Foundation, version 2 of the License.
   44.13 +
   44.14 +    This program is distributed in the hope that it will be useful,
   44.15 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
   44.16 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   44.17 +    GNU General Public License for more details.
   44.18 +
   44.19 +    You should have received a copy of the GNU General Public License
   44.20 +    along with this program. Look for COPYING file in the top folder.
   44.21 +    If not, see http://opensource.org/licenses/GPL-2.0.
   44.22 +
   44.23 +-->
   44.24 +<archetype-descriptor name="bck2brwsr">
   44.25 +  <fileSets>
   44.26 +    <fileSet filtered="true" packaged="true">
   44.27 +      <directory>src/main/java</directory>
   44.28 +      <includes>
   44.29 +        <include>**/*.java</include>
   44.30 +      </includes>
   44.31 +    </fileSet>
   44.32 +    <fileSet filtered="true" packaged="true">
   44.33 +      <directory>src/main/resources</directory>
   44.34 +      <includes>
   44.35 +        <include>**/*.xhtml</include>
   44.36 +      </includes>
   44.37 +    </fileSet>
   44.38 +    <fileSet filtered="false" packaged="false">
   44.39 +      <directory></directory>
   44.40 +      <includes>
   44.41 +        <include>nbactions.xml</include>
   44.42 +      </includes>
   44.43 +    </fileSet>
   44.44 +  </fileSets>    
   44.45 +</archetype-descriptor>
   44.46 \ No newline at end of file
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/mojo/src/main/resources/archetype-resources/nbactions.xml	Fri Jan 11 16:36:28 2013 +0100
    45.3 @@ -0,0 +1,10 @@
    45.4 +<?xml version="1.0" encoding="UTF-8"?>
    45.5 +<actions>
    45.6 +    <action>
    45.7 +        <actionName>run</actionName>
    45.8 +        <goals>
    45.9 +            <goal>process-classes</goal>
   45.10 +            <goal>org.apidesign.bck2brwsr:mojo:0.3-SNAPSHOT:brwsr</goal>
   45.11 +        </goals>
   45.12 +    </action>
   45.13 +</actions>
    46.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.2 +++ b/mojo/src/main/resources/archetype-resources/pom.xml	Fri Jan 11 16:36:28 2013 +0100
    46.3 @@ -0,0 +1,57 @@
    46.4 +<?xml version="1.0"?>
    46.5 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    46.6 +  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    46.7 +  <modelVersion>4.0.0</modelVersion>
    46.8 +
    46.9 +  <groupId>${groupId}</groupId>
   46.10 +  <artifactId>${artifactId}</artifactId>
   46.11 +  <version>${version}</version>
   46.12 +  <packaging>jar</packaging>
   46.13 +
   46.14 +  <name>${artifactId}</name>
   46.15 +
   46.16 +  <properties>
   46.17 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   46.18 +  </properties>
   46.19 +  <build>
   46.20 +      <plugins>
   46.21 +            <plugin>
   46.22 +                <groupId>org.apidesign.bck2brwsr</groupId>
   46.23 +                <artifactId>mojo</artifactId>
   46.24 +                <version>0.3-SNAPSHOT</version>
   46.25 +                <executions>
   46.26 +                    <execution>
   46.27 +                        <goals>
   46.28 +                            <goal>brwsr</goal>
   46.29 +                        </goals>
   46.30 +                    </execution>
   46.31 +                </executions>
   46.32 +                <configuration>
   46.33 +                    <startpage>${package.replace('.','/')}/index.xhtml</startpage>
   46.34 +                </configuration>
   46.35 +            </plugin>
   46.36 +         <plugin>
   46.37 +            <groupId>org.apache.maven.plugins</groupId>
   46.38 +            <artifactId>maven-compiler-plugin</artifactId>
   46.39 +            <version>2.3.2</version>
   46.40 +            <configuration>
   46.41 +               <source>1.7</source>
   46.42 +               <target>1.7</target>
   46.43 +            </configuration>
   46.44 +         </plugin>
   46.45 +      </plugins>
   46.46 +  </build>
   46.47 +
   46.48 +  <dependencies>
   46.49 +    <dependency>
   46.50 +      <groupId>org.apidesign.bck2brwsr</groupId>
   46.51 +      <artifactId>emul</artifactId>
   46.52 +      <version>0.3-SNAPSHOT</version>
   46.53 +    </dependency>
   46.54 +    <dependency>
   46.55 +      <groupId>org.apidesign.bck2brwsr</groupId>
   46.56 +      <artifactId>javaquery.api</artifactId>
   46.57 +      <version>0.3-SNAPSHOT</version>
   46.58 +    </dependency>
   46.59 +  </dependencies>
   46.60 +</project>
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/mojo/src/main/resources/archetype-resources/src/main/java/App.java	Fri Jan 11 16:36:28 2013 +0100
    47.3 @@ -0,0 +1,15 @@
    47.4 +package ${package};
    47.5 +
    47.6 +import org.apidesign.bck2brwsr.htmlpage.api.OnClick;
    47.7 +import org.apidesign.bck2brwsr.htmlpage.api.Page;
    47.8 +
    47.9 +/** Edit the index.xhtml file. Use 'id' to name certain HTML elements.
   47.10 + * Use this class to define behavior of the elements.
   47.11 + */
   47.12 +@Page(xhtml="index.xhtml", className="Index")
   47.13 +public class App {
   47.14 +    @OnClick(id="hello")
   47.15 +    static void hello() {
   47.16 +        Index.HELLO.setDisabled(true);
   47.17 +    }
   47.18 +}
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/mojo/src/main/resources/archetype-resources/src/main/resources/index.xhtml	Fri Jan 11 16:36:28 2013 +0100
    48.3 @@ -0,0 +1,16 @@
    48.4 +<?xml version="1.0" encoding="UTF-8"?>
    48.5 +<!DOCTYPE html>
    48.6 +<html xmlns="http://www.w3.org/1999/xhtml">
    48.7 +    <head>
    48.8 +        <title>Bck2Brwsr's Hello World</title>
    48.9 +    </head>
   48.10 +    <body>
   48.11 +        <button id="hello">Hello World!</button>
   48.12 +
   48.13 +        <script src="/bck2brwsr.js"></script>
   48.14 +        <script src="/vm.js"></script>
   48.15 +        <script type="text/javascript">
   48.16 +            vm.loadClass('${package}.Index');
   48.17 +        </script>
   48.18 +    </body>
   48.19 +</html>
    49.1 --- a/pom.xml	Fri Jan 11 16:07:55 2013 +0100
    49.2 +++ b/pom.xml	Fri Jan 11 16:36:28 2013 +0100
    49.3 @@ -14,6 +14,8 @@
    49.4      <module>javaquery</module>
    49.5      <module>javap</module>
    49.6      <module>benchmarks</module>
    49.7 +    <module>launcher</module>
    49.8 +    <module>vmtest</module>
    49.9    </modules>
   49.10    <licenses>
   49.11        <license>
   49.12 @@ -71,6 +73,8 @@
   49.13                         <exclude>javap/**</exclude>
   49.14                         <exclude>*</exclude>
   49.15                         <exclude>.*/**</exclude>
   49.16 +                       <exclude>mojo/src/main/resources/archetype-resources/**</exclude>
   49.17 +                       <exclude>vmtest/src/test/resources/**</exclude>
   49.18                    </excludes>
   49.19                </configuration>
   49.20            </plugin>
   49.21 @@ -108,4 +112,4 @@
   49.22    <properties>
   49.23        <license>COPYING</license>
   49.24    </properties>
   49.25 -</project>
   49.26 +</project>
   49.27 \ No newline at end of file
    50.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Fri Jan 11 16:07:55 2013 +0100
    50.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/Bck2Brwsr.java	Fri Jan 11 16:36:28 2013 +0100
    50.3 @@ -37,7 +37,7 @@
    50.4   *   return null; // byte[] for the resource
    50.5   * });
    50.6   * </pre>
    50.7 - * In this scenario, when a request for a unknown class is made, the loader
    50.8 + * In this scenario, when a request for an unknown class is made, the loader
    50.9   * function is asked for its byte code and the system dynamically transforms
   50.10   * it to JavaScript.
   50.11   *
    51.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Fri Jan 11 16:07:55 2013 +0100
    51.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Fri Jan 11 16:36:28 2013 +0100
    51.3 @@ -25,6 +25,8 @@
    51.4  import org.apidesign.javap.MethodData;
    51.5  import org.apidesign.javap.StackMapIterator;
    51.6  import static org.apidesign.javap.RuntimeConstants.*;
    51.7 +import org.apidesign.javap.TrapData;
    51.8 +import org.apidesign.javap.TrapDataIterator;
    51.9  
   51.10  /** Translator of the code inside class files to JavaScript.
   51.11   *
   51.12 @@ -63,6 +65,17 @@
   51.13      /* protected */ String accessClass(String classOperation) {
   51.14          return classOperation;
   51.15      }
   51.16 +    
   51.17 +    /** Prints out a debug message. 
   51.18 +     * 
   51.19 +     * @param msg the message
   51.20 +     * @return true if the message has been printed
   51.21 +     * @throws IOException 
   51.22 +     */
   51.23 +    boolean debug(String msg) throws IOException {
   51.24 +        out.append(msg);
   51.25 +        return true;
   51.26 +    }
   51.27  
   51.28      /**
   51.29       * Converts a given class file to a JavaScript version.
   51.30 @@ -133,18 +146,27 @@
   51.31                  }
   51.32                  continue;
   51.33              }
   51.34 +            String prefix;
   51.35              String mn;
   51.36              if (m.isStatic()) {
   51.37 -                mn = generateStaticMethod("\n    c.", m, toInitilize);
   51.38 +                prefix = "\n    c.";
   51.39 +                mn = generateStaticMethod(prefix, m, toInitilize);
   51.40              } else {
   51.41 -                mn = generateInstanceMethod("\n    c.", m);
   51.42 +                if (m.isConstructor()) {
   51.43 +                    prefix = "\n    CLS.";
   51.44 +                    mn = generateInstanceMethod(prefix, m);
   51.45 +                } else {
   51.46 +                    prefix = "\n    c.";
   51.47 +                    mn = generateInstanceMethod(prefix, m);
   51.48 +                }
   51.49              }
   51.50              byte[] runAnno = m.findAnnotationData(false);
   51.51              if (runAnno != null) {
   51.52 -                out.append("\n    c.").append(mn).append(".anno = {");
   51.53 +                out.append(prefix).append(mn).append(".anno = {");
   51.54                  generateAnno(jc, out, runAnno);
   51.55                  out.append("\n    };");
   51.56              }
   51.57 +            out.append(prefix).append(mn).append(".access = " + m.getAccess()).append(";");
   51.58          }
   51.59          out.append("\n    c.constructor = CLS;");
   51.60          out.append("\n    c.$instOf_").append(className).append(" = true;");
   51.61 @@ -155,6 +177,7 @@
   51.62          out.append(accessClass("java_lang_Class(true);"));
   51.63          out.append("\n    CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
   51.64          out.append("\n    CLS.$class.superclass = sprcls;");
   51.65 +        out.append("\n    CLS.$class.access = ").append(jc.getAccessFlags()+";");
   51.66          out.append("\n    CLS.$class.cnstr = CLS;");
   51.67          byte[] classAnno = jc.findAnnotationData(false);
   51.68          if (classAnno != null) {
   51.69 @@ -221,6 +244,7 @@
   51.70      private void generateMethod(String prefix, String name, MethodData m)
   51.71              throws IOException {
   51.72          final StackMapIterator stackMapIterator = m.createStackMapIterator();
   51.73 +        TrapDataIterator trap = m.getTrapDataIterator();
   51.74          final LocalsMapper lmapper =
   51.75                  new LocalsMapper(stackMapIterator.getArguments());
   51.76  
   51.77 @@ -231,7 +255,8 @@
   51.78          final byte[] byteCodes = m.getCode();
   51.79          if (byteCodes == null) {
   51.80              out.append("  throw 'no code found for ")
   51.81 -               .append(m.getInternalSig()).append("';\n");
   51.82 +               .append(jc.getClassName()).append('.')
   51.83 +               .append(m.getName()).append("';\n");
   51.84              out.append("};");
   51.85              return;
   51.86          }
   51.87 @@ -267,18 +292,31 @@
   51.88          }
   51.89  
   51.90          int lastStackFrame = -1;
   51.91 -
   51.92 +        TrapData[] previousTrap = null;
   51.93 +        
   51.94          out.append("\n  var gt = 0;\n  for(;;) switch(gt) {\n");
   51.95          for (int i = 0; i < byteCodes.length; i++) {
   51.96              int prev = i;
   51.97              stackMapIterator.advanceTo(i);
   51.98 +            boolean changeInCatch = trap.advanceTo(i);
   51.99 +            if (changeInCatch || lastStackFrame != stackMapIterator.getFrameIndex()) {
  51.100 +                if (previousTrap != null) {
  51.101 +                    generateCatch(previousTrap);
  51.102 +                    previousTrap = null;
  51.103 +                }
  51.104 +            }
  51.105              if (lastStackFrame != stackMapIterator.getFrameIndex()) {
  51.106                  lastStackFrame = stackMapIterator.getFrameIndex();
  51.107                  lmapper.syncWithFrameLocals(stackMapIterator.getFrameLocals());
  51.108                  smapper.syncWithFrameStack(stackMapIterator.getFrameStack());
  51.109 -                out.append("    case " + i).append(": ");
  51.110 +                out.append("    case " + i).append(": ");            
  51.111 +                changeInCatch = true;
  51.112              } else {
  51.113 -                out.append("    /* " + i).append(" */ ");
  51.114 +                debug("    /* " + i + " */ ");
  51.115 +            }
  51.116 +            if (changeInCatch && trap.useTry()) {
  51.117 +                out.append("try {");
  51.118 +                previousTrap = trap.current();
  51.119              }
  51.120              final int c = readByte(byteCodes, i);
  51.121              switch (c) {
  51.122 @@ -950,7 +988,7 @@
  51.123                  case opc_pop:
  51.124                  case opc_pop2:
  51.125                      smapper.pop(1);
  51.126 -                    out.append("/* pop */");
  51.127 +                    debug("/* pop */");
  51.128                      break;
  51.129                  case opc_dup: {
  51.130                      final Variable v = smapper.get(0);
  51.131 @@ -1028,7 +1066,7 @@
  51.132                      int indx = readIntArg(byteCodes, i);
  51.133                      String[] fi = jc.getFieldInfoName(indx);
  51.134                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  51.135 -                    emit(out, "@1 = @2.@3;",
  51.136 +                    emit(out, "@1 = @2(false).constructor.@3;",
  51.137                           smapper.pushT(type),
  51.138                           accessClass(fi[0].replace('/', '_')), fi[1]);
  51.139                      i += 2;
  51.140 @@ -1048,7 +1086,7 @@
  51.141                      int indx = readIntArg(byteCodes, i);
  51.142                      String[] fi = jc.getFieldInfoName(indx);
  51.143                      final int type = VarType.fromFieldType(fi[2].charAt(0));
  51.144 -                    emit(out, "@1.@2 = @3;",
  51.145 +                    emit(out, "@1(false).constructor.@2 = @3;",
  51.146                           accessClass(fi[0].replace('/', '_')), fi[1],
  51.147                           smapper.popT(type));
  51.148                      i += 2;
  51.149 @@ -1103,13 +1141,17 @@
  51.150                           Integer.toString(c));
  51.151                  }
  51.152              }
  51.153 -            out.append(" //");
  51.154 -            for (int j = prev; j <= i; j++) {
  51.155 -                out.append(" ");
  51.156 -                final int cc = readByte(byteCodes, j);
  51.157 -                out.append(Integer.toString(cc));
  51.158 +            if (debug(" //")) {
  51.159 +                for (int j = prev; j <= i; j++) {
  51.160 +                    out.append(" ");
  51.161 +                    final int cc = readByte(byteCodes, j);
  51.162 +                    out.append(Integer.toString(cc));
  51.163 +                }
  51.164              }
  51.165 -            out.append("\n");
  51.166 +            out.append("\n");            
  51.167 +        }
  51.168 +        if (previousTrap != null) {
  51.169 +            generateCatch(previousTrap);
  51.170          }
  51.171          out.append("  }\n");
  51.172          out.append("};");
  51.173 @@ -1208,6 +1250,7 @@
  51.174                          returnType[0] = 'L';
  51.175                      }
  51.176                      i = next + 1;
  51.177 +                    array = false;
  51.178                      continue;
  51.179                  case '[':
  51.180                      array = true;
  51.181 @@ -1283,6 +1326,9 @@
  51.182          final String in = mi[0];
  51.183          out.append(accessClass(in.replace('/', '_')));
  51.184          out.append("(false).");
  51.185 +        if (mn.startsWith("cons_")) {
  51.186 +            out.append("constructor.");
  51.187 +        }
  51.188          out.append(mn);
  51.189          out.append('(');
  51.190          if (numArguments > 0) {
  51.191 @@ -1332,7 +1378,7 @@
  51.192  
  51.193      private void addReference(String cn) throws IOException {
  51.194          if (requireReference(cn)) {
  51.195 -            out.append(" /* needs ").append(cn).append(" */");
  51.196 +            debug(" /* needs " + cn + " */");
  51.197          }
  51.198      }
  51.199  
  51.200 @@ -1538,4 +1584,39 @@
  51.201  
  51.202          out.append(format, processed, length);
  51.203      }
  51.204 +
  51.205 +    private void generateCatch(TrapData[] traps) throws IOException {
  51.206 +        out.append("} catch (e) {\n");
  51.207 +        int finallyPC = -1;
  51.208 +        for (TrapData e : traps) {
  51.209 +            if (e == null) {
  51.210 +                break;
  51.211 +            }
  51.212 +            if (e.catch_cpx != 0) { //not finally
  51.213 +                final String classInternalName = jc.getClassName(e.catch_cpx);
  51.214 +                addReference(classInternalName);
  51.215 +                if ("java/lang/Throwable".equals(classInternalName)) {
  51.216 +                    out.append("if (e.$instOf_java_lang_Throwable) {");
  51.217 +                    out.append("  stA0 = e;");
  51.218 +                    out.append("} else {");
  51.219 +                    out.append("  stA0 = vm.java_lang_Throwable(true);");
  51.220 +                    out.append("  vm.java_lang_Throwable.cons__VLjava_lang_String_2(stA0, e.toString());");
  51.221 +                    out.append("}");
  51.222 +                    out.append("gt=" + e.handler_pc + "; continue;");
  51.223 +                } else {
  51.224 +                    out.append("if (e.$instOf_" + classInternalName.replace('/', '_') + ") {");
  51.225 +                    out.append("gt=" + e.handler_pc + "; stA0 = e; continue;");
  51.226 +                    out.append("}\n");
  51.227 +                }
  51.228 +            } else {
  51.229 +                finallyPC = e.handler_pc;
  51.230 +            }
  51.231 +        }
  51.232 +        if (finallyPC == -1) {
  51.233 +            out.append("throw e;");
  51.234 +        } else {
  51.235 +            out.append("gt=" + finallyPC + "; stA0 = e; continue;");
  51.236 +        }
  51.237 +        out.append("\n}");
  51.238 +    }
  51.239  }
    52.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Fri Jan 11 16:07:55 2013 +0100
    52.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VM.java	Fri Jan 11 16:36:28 2013 +0100
    52.3 @@ -33,6 +33,11 @@
    52.4          // uses VMLazy to load dynamic classes
    52.5          VMLazy.init();
    52.6      }
    52.7 +
    52.8 +    @Override
    52.9 +    boolean debug(String msg) throws IOException {
   52.10 +        return false;
   52.11 +    }
   52.12      
   52.13      static void compile(Bck2Brwsr.Resources l, Appendable out, StringArray names) throws IOException {
   52.14          new VM(out).doCompile(l, names);
   52.15 @@ -117,9 +122,15 @@
   52.16              + "      if (fn) return fn(false);\n"
   52.17              + "      if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
   52.18              + "      return vm.org_apidesign_vm4brwsr_VMLazy(false).\n"
   52.19 -            + "        load___3Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
   52.20 +            + "        load__Ljava_lang_Object_2Ljava_lang_Object_2Ljava_lang_String_2_3Ljava_lang_Object_2(loader, name, args);\n"
   52.21              + "    }\n"
   52.22 -            + "    if (args[0]) vm.loadClass = loader.loadClass;\n"
   52.23 +            + "    if (args[0]) {\n"
   52.24 +            + "      vm.loadClass = loader.loadClass;\n"
   52.25 +            + "      vm.loadBytes = function(name) {\n"
   52.26 +            + "        if (!args[0]) throw 'bck2brwsr initialized without loader function, cannot load ' + name;\n"
   52.27 +            + "        return args[0](name);\n"
   52.28 +            + "      }\n"
   52.29 +            + "    }\n"
   52.30              + "    return loader;\n"
   52.31              + "  };\n");
   52.32          out.append("}(this));");
    53.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java	Fri Jan 11 16:07:55 2013 +0100
    53.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/VMLazy.java	Fri Jan 11 16:36:28 2013 +0100
    53.3 @@ -61,10 +61,27 @@
    53.4          StringBuilder out = new StringBuilder();
    53.5          out.append("var loader = arguments[0];\n");
    53.6          out.append("var vm = loader.vm;\n");
    53.7 -        new Gen(this, out).compile(new ByteArrayInputStream(arr));
    53.8 +        int prelude = out.length();
    53.9 +        String initCode = new Gen(this, out).compile(new ByteArrayInputStream(arr));
   53.10          String code = out.toString().toString();
   53.11 +//        dump("Loading " + name);
   53.12 +        dump(code);
   53.13          String under = name.replace('.', '_');
   53.14 -        return applyCode(loader, under, code, instance);
   53.15 +        Object fn = applyCode(loader, under, code, instance);
   53.16 +        
   53.17 +        if (!initCode.isEmpty()) {
   53.18 +            out.setLength(prelude);
   53.19 +            out.append(initCode);
   53.20 +            code = out.toString().toString();
   53.21 +            dump(code);
   53.22 +            applyCode(loader, null, code, false);
   53.23 +        }            
   53.24 +        
   53.25 +        return fn;
   53.26 +    }
   53.27 +
   53.28 +//    @JavaScriptBody(args = "s", body = "java.lang.System.out.println(s.toString());")
   53.29 +    static void dump(String s) {
   53.30      }
   53.31  
   53.32  /* possibly not needed:
   53.33 @@ -82,7 +99,7 @@
   53.34          "} catch (ex) {\n" +
   53.35          "  throw 'Cannot compile ' + ex + ' line: ' + ex.lineNumber + ' script:\\n' + script;\n" +
   53.36          "}\n" +
   53.37 -        "return vm[name](instance);\n"
   53.38 +        "return name != null ? vm[name](instance) : null;\n"
   53.39      )
   53.40      private static native Object applyCode(Object loader, String name, String script, boolean instance);
   53.41      
    54.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Fri Jan 11 16:07:55 2013 +0100
    54.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Fri Jan 11 16:36:28 2013 +0100
    54.3 @@ -82,11 +82,17 @@
    54.4          }
    54.5          return sum;
    54.6      }
    54.7 -    public static int simple() {
    54.8 -        int[] arr = { 0, 1, 2, 3, 4, 5 };
    54.9 +    private static final int[] arr = { 0, 1, 2, 3, 4, 5 };
   54.10 +    public static int simple(boolean clone) {
   54.11 +        int[] ar;
   54.12 +        if (clone) {
   54.13 +            ar = arr.clone();
   54.14 +        } else {
   54.15 +            ar = arr;
   54.16 +        }
   54.17          
   54.18          int sum = 0;
   54.19 -        for (int a : arr) {
   54.20 +        for (int a : ar) {
   54.21              sum += a;
   54.22          }
   54.23          return sum;
    55.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java	Fri Jan 11 16:07:55 2013 +0100
    55.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java	Fri Jan 11 16:36:28 2013 +0100
    55.3 @@ -18,7 +18,6 @@
    55.4  package org.apidesign.vm4brwsr;
    55.5  
    55.6  import javax.script.Invocable;
    55.7 -import javax.script.ScriptException;
    55.8  import static org.testng.Assert.*;
    55.9  import org.testng.annotations.BeforeClass;
   55.10  import org.testng.annotations.Test;
   55.11 @@ -29,8 +28,14 @@
   55.12   */
   55.13  public class ArrayTest {
   55.14      @Test public void verifySimpleIntOperation() throws Exception {
   55.15 -            assertExec("CheckTheSum", Array.class, "simple__I", 
   55.16 -            Double.valueOf(15)
   55.17 +            assertExec("CheckTheSum", Array.class, "simple__IZ", 
   55.18 +            Double.valueOf(15), false
   55.19 +        );
   55.20 +    }
   55.21 +    
   55.22 +    @Test public void cloneOnArray() throws Exception {
   55.23 +            assertExec("CheckTheSum on clone", Array.class, "simple__IZ", 
   55.24 +            Double.valueOf(15), true
   55.25          );
   55.26      }
   55.27      
    56.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java	Fri Jan 11 16:07:55 2013 +0100
    56.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ClassTest.java	Fri Jan 11 16:36:28 2013 +0100
    56.3 @@ -74,6 +74,16 @@
    56.4      @Test public void jsNewInstance() throws Exception {
    56.5          assertExec("Check new instance", Classes.class, "newInstance__Z", Double.valueOf(1));
    56.6      }
    56.7 +    @Test public void javaNoNewInstance() throws Exception {
    56.8 +        assertEquals("java.lang.InstantiationException:java.lang.Float", 
    56.9 +            Classes.newInstanceNoPubConstructor()
   56.10 +        );
   56.11 +    }
   56.12 +    @Test public void jsNoNewInstance() throws Exception {
   56.13 +        assertExec("Check problems with new instance", Classes.class, "newInstanceNoPubConstructor__Ljava_lang_String_2", 
   56.14 +            "java.lang.InstantiationException:java.lang.Float"
   56.15 +        );
   56.16 +    }
   56.17      @Test public void jsAnnotation() throws Exception {
   56.18          assertExec("Check class annotation", Classes.class, "getMarker__I", Double.valueOf(10));
   56.19      }
   56.20 @@ -92,6 +102,11 @@
   56.21              "java.io.IOException", true, "name"
   56.22          );
   56.23      }
   56.24 +    @Test public void jsInvokeParamMethod() throws Exception {
   56.25 +        assertExec("sums two numbers via reflection", Classes.class, 
   56.26 +            "reflectiveSum__III", Double.valueOf(5), 2, 3
   56.27 +        );
   56.28 +    }
   56.29      @Test public void javaFindMethod() throws Exception {
   56.30          assertEquals(Classes.reflectiveMethodCall(false, "name"), "java.io.IOException", "Calls the name() method via reflection");
   56.31      }
   56.32 @@ -101,6 +116,18 @@
   56.33              "java.io.IOException", false, "name"
   56.34          );
   56.35      }
   56.36 +    @Test public void primitiveReturnType() throws Exception {
   56.37 +        assertExec("Tries to get an integer via reflection", Classes.class, 
   56.38 +            "primitiveType__Ljava_lang_String_2Ljava_lang_String_2", 
   56.39 +            Classes.primitiveType("primitive"), "primitive"
   56.40 +        );
   56.41 +    }
   56.42 +    @Test public void primitiveBoolReturnType() throws Exception {
   56.43 +        assertExec("Tries to get an integer via reflection", Classes.class, 
   56.44 +            "primitiveType__Ljava_lang_String_2Ljava_lang_String_2", 
   56.45 +            Classes.primitiveType("primitiveB"), "primitiveB"
   56.46 +        );
   56.47 +    }
   56.48      @Test public void javaAnnotatedMethod() throws Exception {
   56.49          assertEquals(Classes.reflectiveMethodCall(false, null), "java.io.IOException", "Calls the name() method via reflection");
   56.50      }
   56.51 @@ -116,6 +143,26 @@
   56.52              "java.io.IOException"
   56.53          );
   56.54      }
   56.55 +    @Test public void noInterface() throws Exception {
   56.56 +        assertExec("Calls Class.isInterface", Classes.class, 
   56.57 +            "isInterface__ZLjava_lang_String_2", 
   56.58 +            0.0, "java.lang.String"
   56.59 +        );
   56.60 +    }
   56.61 +    /*
   56.62 +    @Test public void isInterface() throws Exception {
   56.63 +        assertExec("Calls Class.isInterface", Classes.class, 
   56.64 +            "isInterface__ZLjava_lang_String_2", 
   56.65 +            1.0, "java.lang.Runnable"
   56.66 +        );
   56.67 +    }
   56.68 +    */
   56.69 +    @Test public void integerType() throws Exception {
   56.70 +        assertExec("Computes the type", Classes.class, 
   56.71 +            "intType__Ljava_lang_String_2", 
   56.72 +            Classes.intType()
   56.73 +        );
   56.74 +    }
   56.75      
   56.76      private static CharSequence codeSeq;
   56.77      private static Invocable code;
    57.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java	Fri Jan 11 16:07:55 2013 +0100
    57.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Classes.java	Fri Jan 11 16:36:28 2013 +0100
    57.3 @@ -38,6 +38,10 @@
    57.4          return c.getName();
    57.5      }
    57.6      
    57.7 +    public static boolean isInterface(String s) throws ClassNotFoundException {
    57.8 +        return Class.forName(s).isInterface();
    57.9 +    }
   57.10 +    
   57.11      public static boolean equalsClassesOfExceptions() {
   57.12          return MalformedURLException.class.getSuperclass() == IOException.class;
   57.13      }
   57.14 @@ -68,6 +72,14 @@
   57.15          }
   57.16          throw new IllegalStateException("Not a subtype: " + ioe);
   57.17      }
   57.18 +    public static String newInstanceNoPubConstructor() throws Exception {
   57.19 +        try {
   57.20 +            Float f = Float.class.newInstance();
   57.21 +            return "wrong, can't instantiate: " + f;
   57.22 +        } catch (Exception ex) {
   57.23 +            return (ex.getClass().getName() + ":" + ex.getMessage()).toString().toString();
   57.24 +        }
   57.25 +    }
   57.26      public static int getMarker() {
   57.27          if (!Classes.class.isAnnotationPresent(ClassesMarker.class)) {
   57.28              return -2;
   57.29 @@ -88,6 +100,21 @@
   57.30          return null;
   57.31      }
   57.32      
   57.33 +    public static String intType() {
   57.34 +        return Integer.TYPE.getName();
   57.35 +    }
   57.36 +    
   57.37 +    public static int primitive() {
   57.38 +        return 1;
   57.39 +    }
   57.40 +    public static boolean primitiveB() {
   57.41 +        return true;
   57.42 +    }
   57.43 +    
   57.44 +    public static String primitiveType(String method) throws Exception {
   57.45 +        return reflectiveMethodCall(false, method).getClass().getName();
   57.46 +    }
   57.47 +    
   57.48      @JavaScriptBody(args = "msg", body = "throw msg;")
   57.49      private static native void thrw(String msg);
   57.50      
   57.51 @@ -119,4 +146,9 @@
   57.52          }
   57.53          return find.invoke(null);
   57.54      }
   57.55 +    
   57.56 +    public static int reflectiveSum(int a, int b) throws Exception {
   57.57 +        Method m = StaticMethod.class.getMethod("sum", int.class, int.class);
   57.58 +        return (int) m.invoke(null, a, b);
   57.59 +    }
   57.60  }
    58.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/Compare.java	Fri Jan 11 16:07:55 2013 +0100
    58.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.3 @@ -1,36 +0,0 @@
    58.4 -/**
    58.5 - * Back 2 Browser Bytecode Translator
    58.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    58.7 - *
    58.8 - * This program is free software: you can redistribute it and/or modify
    58.9 - * it under the terms of the GNU General Public License as published by
   58.10 - * the Free Software Foundation, version 2 of the License.
   58.11 - *
   58.12 - * This program is distributed in the hope that it will be useful,
   58.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   58.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   58.15 - * GNU General Public License for more details.
   58.16 - *
   58.17 - * You should have received a copy of the GNU General Public License
   58.18 - * along with this program. Look for COPYING file in the top folder.
   58.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   58.20 - */
   58.21 -package org.apidesign.vm4brwsr;
   58.22 -
   58.23 -import java.lang.annotation.ElementType;
   58.24 -import java.lang.annotation.Retention;
   58.25 -import java.lang.annotation.RetentionPolicy;
   58.26 -import java.lang.annotation.Target;
   58.27 -
   58.28 -/** Can be applied on a method that yields a return value. 
   58.29 - * Together with {@link VMCompare#create} it can be used to write
   58.30 - * methods which are executed in real as well as JavaScript VMs and
   58.31 - * their results are compared.
   58.32 - *
   58.33 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   58.34 - */
   58.35 -@Retention(RetentionPolicy.RUNTIME)
   58.36 -@Target(ElementType.METHOD)
   58.37 -public @interface Compare {
   58.38 -    
   58.39 -}
    59.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/CompareVMs.java	Fri Jan 11 16:07:55 2013 +0100
    59.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.3 @@ -1,197 +0,0 @@
    59.4 -/**
    59.5 - * Back 2 Browser Bytecode Translator
    59.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    59.7 - *
    59.8 - * This program is free software: you can redistribute it and/or modify
    59.9 - * it under the terms of the GNU General Public License as published by
   59.10 - * the Free Software Foundation, version 2 of the License.
   59.11 - *
   59.12 - * This program is distributed in the hope that it will be useful,
   59.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   59.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   59.15 - * GNU General Public License for more details.
   59.16 - *
   59.17 - * You should have received a copy of the GNU General Public License
   59.18 - * along with this program. Look for COPYING file in the top folder.
   59.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   59.20 - */
   59.21 -package org.apidesign.vm4brwsr;
   59.22 -
   59.23 -import java.lang.reflect.Method;
   59.24 -import java.util.Map;
   59.25 -import java.util.WeakHashMap;
   59.26 -import javax.script.Invocable;
   59.27 -import javax.script.ScriptContext;
   59.28 -import javax.script.ScriptEngine;
   59.29 -import javax.script.ScriptEngineManager;
   59.30 -import org.testng.Assert;
   59.31 -import org.testng.ITest;
   59.32 -import org.testng.annotations.Factory;
   59.33 -import org.testng.annotations.Test;
   59.34 -
   59.35 -/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
   59.36 - * in provided class and builds set of tests that compare the computations
   59.37 - * in real as well as JavaScript virtual machines. Use as:<pre>
   59.38 - * {@code @}{@link Factory} public static create() {
   59.39 - *   return @{link CompareVMs}.{@link #create(YourClass.class);
   59.40 - * }</pre>
   59.41 - *
   59.42 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   59.43 - */
   59.44 -public final class CompareVMs implements ITest {
   59.45 -    private final Run first, second;
   59.46 -    private final Method m;
   59.47 -    
   59.48 -    private CompareVMs(Method m, Run first, Run second) {
   59.49 -        this.first = first;
   59.50 -        this.second = second;
   59.51 -        this.m = m;
   59.52 -    }
   59.53 -
   59.54 -    public static Object[] create(Class<?> clazz) {
   59.55 -        Method[] arr = clazz.getMethods();
   59.56 -        Object[] ret = new Object[3 * arr.length];
   59.57 -        int cnt = 0;
   59.58 -        for (Method m : arr) {
   59.59 -            Compare c = m.getAnnotation(Compare.class);
   59.60 -            if (c == null) {
   59.61 -                continue;
   59.62 -            }
   59.63 -            final Run real = new Run(m, false);
   59.64 -            final Run js = new Run(m, true);
   59.65 -            ret[cnt++] = real;
   59.66 -            ret[cnt++] = js;
   59.67 -            ret[cnt++] = new CompareVMs(m, real, js);
   59.68 -        }
   59.69 -        Object[] r = new Object[cnt];
   59.70 -        for (int i = 0; i < cnt; i++) {
   59.71 -            r[i] = ret[i];
   59.72 -        }
   59.73 -        return r;
   59.74 -    }
   59.75 -    
   59.76 -    @Test(dependsOnGroups = "run") public void compareResults() throws Throwable {
   59.77 -        Object v1 = first.value;
   59.78 -        Object v2 = second.value;
   59.79 -        if (v1 instanceof Number) {
   59.80 -            v1 = ((Number)v1).doubleValue();
   59.81 -        }
   59.82 -        Assert.assertEquals(v2, v1, "Comparing results");
   59.83 -    }
   59.84 -    
   59.85 -    @Override
   59.86 -    public String getTestName() {
   59.87 -        return m.getName() + "[Compare]";
   59.88 -    }
   59.89 -    
   59.90 -    public static final class Run implements ITest {
   59.91 -        private final Method m;
   59.92 -        private final boolean js;
   59.93 -        Object value;
   59.94 -        private Invocable code;
   59.95 -        private CharSequence codeSeq;
   59.96 -        private static final Map<Class,Object[]> compiled = new WeakHashMap<Class,Object[]>();
   59.97 -
   59.98 -        private Run(Method m, boolean js) {
   59.99 -            this.m = m;
  59.100 -            this.js = js;
  59.101 -        }
  59.102 -
  59.103 -        private void compileTheCode(Class<?> clazz) throws Exception {
  59.104 -            final Object[] data = compiled.get(clazz);
  59.105 -            if (data != null) {
  59.106 -                code = (Invocable) data[0];
  59.107 -                codeSeq = (CharSequence) data[1];
  59.108 -                return;
  59.109 -            }
  59.110 -            StringBuilder sb = new StringBuilder();
  59.111 -            Bck2Brwsr.generate(sb, CompareVMs.class.getClassLoader());
  59.112 -
  59.113 -            ScriptEngineManager sem = new ScriptEngineManager();
  59.114 -            ScriptEngine js = sem.getEngineByExtension("js");
  59.115 -            js.getContext().setAttribute("loader", new BytesLoader(), ScriptContext.ENGINE_SCOPE);
  59.116 -            
  59.117 -            sb.append("\nfunction initVM() {"
  59.118 -                + "\n  return bck2brwsr("
  59.119 -                + "\n    function(name) { return loader.get(name);}"
  59.120 -                + "\n  );"
  59.121 -                + "\n};");
  59.122 -
  59.123 -            Object res = js.eval(sb.toString());
  59.124 -            Assert.assertTrue(js instanceof Invocable, "It is invocable object: " + res);
  59.125 -            code = (Invocable) js;
  59.126 -            codeSeq = sb;
  59.127 -            compiled.put(clazz, new Object[] { code, codeSeq });
  59.128 -        }
  59.129 -
  59.130 -        @Test(groups = "run") public void executeCode() throws Throwable {
  59.131 -            if (js) {
  59.132 -                try {
  59.133 -                    compileTheCode(m.getDeclaringClass());
  59.134 -                    Object vm = code.invokeFunction("initVM");
  59.135 -                    Object inst = code.invokeMethod(vm, "loadClass", m.getDeclaringClass().getName());
  59.136 -                    value = code.invokeMethod(inst, m.getName() + "__" + computeSignature(m));
  59.137 -                } catch (Exception ex) {
  59.138 -                    throw new AssertionError(StaticMethodTest.dumpJS(codeSeq)).initCause(ex);
  59.139 -                }
  59.140 -            } else {
  59.141 -                value = m.invoke(m.getDeclaringClass().newInstance());
  59.142 -            }
  59.143 -        }
  59.144 -        @Override
  59.145 -        public String getTestName() {
  59.146 -            return m.getName() + (js ? "[JavaScript]" : "[Java]");
  59.147 -        }
  59.148 -        
  59.149 -        private static String computeSignature(Method m) {
  59.150 -            StringBuilder sb = new StringBuilder();
  59.151 -            appendType(sb, m.getReturnType());
  59.152 -            for (Class<?> c : m.getParameterTypes()) {
  59.153 -                appendType(sb, c);
  59.154 -            }
  59.155 -            return sb.toString();
  59.156 -        }
  59.157 -        
  59.158 -        private static void appendType(StringBuilder sb, Class<?> t) {
  59.159 -            if (t == null) {
  59.160 -                sb.append('V');
  59.161 -                return;
  59.162 -            }
  59.163 -            if (t.isPrimitive()) {
  59.164 -                int ch = -1;
  59.165 -                if (t == int.class) {
  59.166 -                    ch = 'I';
  59.167 -                }
  59.168 -                if (t == short.class) {
  59.169 -                    ch = 'S';
  59.170 -                }
  59.171 -                if (t == byte.class) {
  59.172 -                    ch = 'B';
  59.173 -                }
  59.174 -                if (t == boolean.class) {
  59.175 -                    ch = 'Z';
  59.176 -                }
  59.177 -                if (t == long.class) {
  59.178 -                    ch = 'J';
  59.179 -                }
  59.180 -                if (t == float.class) {
  59.181 -                    ch = 'F';
  59.182 -                }
  59.183 -                if (t == double.class) {
  59.184 -                    ch = 'D';
  59.185 -                }
  59.186 -                assert ch != -1 : "Unknown primitive type " + t;
  59.187 -                sb.append((char)ch);
  59.188 -                return;
  59.189 -            }
  59.190 -            if (t.isArray()) {
  59.191 -                sb.append("_3");
  59.192 -                appendType(sb, t.getComponentType());
  59.193 -                return;
  59.194 -            }
  59.195 -            sb.append('L');
  59.196 -            sb.append(t.getName().replace('.', '_'));
  59.197 -            sb.append("_2");
  59.198 -        }
  59.199 -    }
  59.200 -}
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Exceptions.java	Fri Jan 11 16:36:28 2013 +0100
    60.3 @@ -0,0 +1,88 @@
    60.4 +/**
    60.5 + * Back 2 Browser Bytecode Translator
    60.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    60.7 + *
    60.8 + * This program is free software: you can redistribute it and/or modify
    60.9 + * it under the terms of the GNU General Public License as published by
   60.10 + * the Free Software Foundation, version 2 of the License.
   60.11 + *
   60.12 + * This program is distributed in the hope that it will be useful,
   60.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   60.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   60.15 + * GNU General Public License for more details.
   60.16 + *
   60.17 + * You should have received a copy of the GNU General Public License
   60.18 + * along with this program. Look for COPYING file in the top folder.
   60.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   60.20 + */
   60.21 +package org.apidesign.vm4brwsr;
   60.22 +
   60.23 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   60.24 +
   60.25 +/**
   60.26 + *
   60.27 + * @author tom
   60.28 + */
   60.29 +public class Exceptions {
   60.30 +    private Exceptions() {
   60.31 +    }
   60.32 +
   60.33 +    public static int methodWithTryCatchNoThrow() {
   60.34 +        int res = 0;
   60.35 +        try {
   60.36 +            res = 1;
   60.37 +        } catch (IllegalArgumentException e) {
   60.38 +            res = 2;
   60.39 +        }
   60.40 +        //join point
   60.41 +        return res;
   60.42 +    }
   60.43 +
   60.44 +    public static int methodWithTryCatchThrow() {
   60.45 +        int res = 0;
   60.46 +        try {
   60.47 +            res = 1;
   60.48 +            throw new IllegalArgumentException();
   60.49 +        } catch (IllegalArgumentException e) {
   60.50 +            res = 2;
   60.51 +        }
   60.52 +        //join point
   60.53 +        return res;
   60.54 +    }
   60.55 +    
   60.56 +    @JavaScriptBody(args = "msg", body = "throw msg;")
   60.57 +    public static void thrw(String msg) {}
   60.58 +    
   60.59 +    public static String catchThrowableCatchesAll() {
   60.60 +        try {
   60.61 +            thrw("Hello!");
   60.62 +            return "Not here!";
   60.63 +        } catch (Throwable ex) {
   60.64 +            return ex.getMessage();
   60.65 +        }
   60.66 +    }
   60.67 +
   60.68 +    public static String newInstance(String n) {
   60.69 +        try {
   60.70 +            Class c;
   60.71 +            try {
   60.72 +                c = Class.forName(n);
   60.73 +            } catch (ClassNotFoundException ex) {
   60.74 +                return ("CNFE:" + ex.getMessage()).toString();
   60.75 +            }
   60.76 +            return c.newInstance().getClass().getName();
   60.77 +        } catch (InstantiationException | IllegalAccessException ex) {
   60.78 +            return ex.getMessage();
   60.79 +        }
   60.80 +    }
   60.81 +    
   60.82 +    private static int counter;
   60.83 +    public static int readCounter(String n) throws ClassNotFoundException {
   60.84 +        try {
   60.85 +            Class.forName(n);
   60.86 +        } finally {
   60.87 +            counter++;
   60.88 +        }
   60.89 +        return counter;
   60.90 +    }
   60.91 +}
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ExceptionsTest.java	Fri Jan 11 16:36:28 2013 +0100
    61.3 @@ -0,0 +1,121 @@
    61.4 +/**
    61.5 + * Back 2 Browser Bytecode Translator
    61.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    61.7 + *
    61.8 + * This program is free software: you can redistribute it and/or modify
    61.9 + * it under the terms of the GNU General Public License as published by
   61.10 + * the Free Software Foundation, version 2 of the License.
   61.11 + *
   61.12 + * This program is distributed in the hope that it will be useful,
   61.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   61.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   61.15 + * GNU General Public License for more details.
   61.16 + *
   61.17 + * You should have received a copy of the GNU General Public License
   61.18 + * along with this program. Look for COPYING file in the top folder.
   61.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   61.20 + */
   61.21 +package org.apidesign.vm4brwsr;
   61.22 +
   61.23 +import javax.script.Invocable;
   61.24 +import javax.script.ScriptException;
   61.25 +import static org.testng.Assert.*;
   61.26 +import org.testng.annotations.BeforeClass;
   61.27 +import org.testng.annotations.Test;
   61.28 +
   61.29 +/**
   61.30 + *
   61.31 + * @author Tomas Zezula <tzezula@netbeans.org>
   61.32 + */
   61.33 +public class ExceptionsTest {
   61.34 +    @Test
   61.35 +    public void verifyMethodWithTryCatchNoThrow() throws Exception {
   61.36 +            assertExec(
   61.37 +                    "No throw",
   61.38 +                    Exceptions.class,
   61.39 +                    "methodWithTryCatchNoThrow__I",
   61.40 +                    new Double(1.0));
   61.41 +    }
   61.42 +
   61.43 +    @Test
   61.44 +    public void catchJavaScriptStringAsThrowable() throws Exception {
   61.45 +        assertExec(
   61.46 +            "Throw hello!",
   61.47 +            Exceptions.class,
   61.48 +            "catchThrowableCatchesAll__Ljava_lang_String_2",
   61.49 +            "Hello!"
   61.50 +        );
   61.51 +    }
   61.52 +
   61.53 +    @Test
   61.54 +    public void verifyMethodWithTryCatchThrow() throws Exception {
   61.55 +            assertExec(
   61.56 +                    "Throw",
   61.57 +                    Exceptions.class,
   61.58 +                    "methodWithTryCatchThrow__I",
   61.59 +                    new Double(2.0));
   61.60 +    }
   61.61 +    
   61.62 +    @Test public void createObject() throws Exception {
   61.63 +        assertExec("Object created", Exceptions.class, 
   61.64 +            "newInstance__Ljava_lang_String_2Ljava_lang_String_2",
   61.65 +            "java.lang.Object",
   61.66 +            "java.lang.Object"
   61.67 +        );
   61.68 +    }
   61.69 +
   61.70 +    @Test public void createFloatFails() throws Exception {
   61.71 +        assertExec("Float not created", Exceptions.class, 
   61.72 +            "newInstance__Ljava_lang_String_2Ljava_lang_String_2",
   61.73 +            "java.lang.Float",
   61.74 +            "java.lang.Float"
   61.75 +        );
   61.76 +    }
   61.77 +
   61.78 +    @Test public void createUnknownFails() throws Exception {
   61.79 +        assertExec("Object created", Exceptions.class, 
   61.80 +            "newInstance__Ljava_lang_String_2Ljava_lang_String_2",
   61.81 +            "CNFE:org.apidesign.Unknown",
   61.82 +            "org.apidesign.Unknown"
   61.83 +        );
   61.84 +    }
   61.85 +    
   61.86 +    @Test public void testThreeCalls() throws Exception {
   61.87 +        Object vm = code.invokeFunction("bck2brwsr");
   61.88 +        Object clazz = code.invokeMethod(vm, "loadClass", Exceptions.class.getName());
   61.89 +        
   61.90 +        String method = "readCounter__ILjava_lang_String_2";
   61.91 +        
   61.92 +        try {
   61.93 +            Object ret = code.invokeMethod(clazz, method, "org.apidesign.Unknown");
   61.94 +            fail("We expect an CNFE!");
   61.95 +        } catch (ScriptException scriptException) {
   61.96 +            // script exception should be OK
   61.97 +        }
   61.98 +        {
   61.99 +            // 2nd invocation
  61.100 +            Object ret = code.invokeMethod(clazz, method, "java.lang.String");
  61.101 +            assertEquals(ret, Double.valueOf(2));
  61.102 +        }
  61.103 +        {
  61.104 +            // 3rd invocation
  61.105 +            Object ret = code.invokeMethod(clazz, method, "java.lang.Integer");
  61.106 +            assertEquals(ret, Double.valueOf(3));
  61.107 +        }
  61.108 +    }
  61.109 +    
  61.110 +    private static CharSequence codeSeq;
  61.111 +    private static Invocable code;
  61.112 +    
  61.113 +    @BeforeClass 
  61.114 +    public void compileTheCode() throws Exception {
  61.115 +        StringBuilder sb = new StringBuilder();
  61.116 +        code = StaticMethodTest.compileClass(sb, 
  61.117 +            "org/apidesign/vm4brwsr/Exceptions"
  61.118 +        );
  61.119 +        codeSeq = sb;
  61.120 +    }
  61.121 +    private static void assertExec(String msg, Class clazz, String method, Object expRes, Object... args) throws Exception {
  61.122 +        StaticMethodTest.assertExec(code, codeSeq, msg, clazz, method, expRes, args);
  61.123 +    }
  61.124 +}
    62.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareHashTest.java	Fri Jan 11 16:07:55 2013 +0100
    62.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.3 @@ -1,46 +0,0 @@
    62.4 -/**
    62.5 - * Back 2 Browser Bytecode Translator
    62.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    62.7 - *
    62.8 - * This program is free software: you can redistribute it and/or modify
    62.9 - * it under the terms of the GNU General Public License as published by
   62.10 - * the Free Software Foundation, version 2 of the License.
   62.11 - *
   62.12 - * This program is distributed in the hope that it will be useful,
   62.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   62.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   62.15 - * GNU General Public License for more details.
   62.16 - *
   62.17 - * You should have received a copy of the GNU General Public License
   62.18 - * along with this program. Look for COPYING file in the top folder.
   62.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   62.20 - */
   62.21 -package org.apidesign.vm4brwsr.tck;
   62.22 -
   62.23 -import org.apidesign.vm4brwsr.Compare;
   62.24 -import org.apidesign.vm4brwsr.CompareVMs;
   62.25 -import org.testng.annotations.Factory;
   62.26 -
   62.27 -/**
   62.28 - *
   62.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   62.30 - */
   62.31 -public class CompareHashTest {
   62.32 -    @Compare public int hashOfString() {
   62.33 -        return "Ahoj".hashCode();
   62.34 -    }
   62.35 -    
   62.36 -    @Compare public int hashRemainsYieldsZero() {
   62.37 -        Object o = new Object();
   62.38 -        return o.hashCode() - o.hashCode();
   62.39 -    }
   62.40 -    
   62.41 -    @Compare public int hashOfInt() {
   62.42 -        return Integer.valueOf(Integer.MAX_VALUE).hashCode();
   62.43 -    }
   62.44 -    
   62.45 -    @Factory
   62.46 -    public static Object[] create() {
   62.47 -        return CompareVMs.create(CompareHashTest.class);
   62.48 -    }
   62.49 -}
    63.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/tck/CompareStringsTest.java	Fri Jan 11 16:07:55 2013 +0100
    63.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.3 @@ -1,110 +0,0 @@
    63.4 -/**
    63.5 - * Back 2 Browser Bytecode Translator
    63.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    63.7 - *
    63.8 - * This program is free software: you can redistribute it and/or modify
    63.9 - * it under the terms of the GNU General Public License as published by
   63.10 - * the Free Software Foundation, version 2 of the License.
   63.11 - *
   63.12 - * This program is distributed in the hope that it will be useful,
   63.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   63.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   63.15 - * GNU General Public License for more details.
   63.16 - *
   63.17 - * You should have received a copy of the GNU General Public License
   63.18 - * along with this program. Look for COPYING file in the top folder.
   63.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   63.20 - */
   63.21 -package org.apidesign.vm4brwsr.tck;
   63.22 -
   63.23 -import java.net.MalformedURLException;
   63.24 -import java.net.URL;
   63.25 -import org.apidesign.vm4brwsr.Compare;
   63.26 -import org.apidesign.vm4brwsr.CompareVMs;
   63.27 -import org.testng.annotations.Factory;
   63.28 -
   63.29 -/**
   63.30 - *
   63.31 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   63.32 - */
   63.33 -public class CompareStringsTest {
   63.34 -    @Compare public static Object compareURLs() throws MalformedURLException {
   63.35 -        return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
   63.36 -    }
   63.37 -    
   63.38 -    @Compare public String deleteLastTwoCharacters() {
   63.39 -        StringBuilder sb = new StringBuilder();
   63.40 -        sb.append("453.0");
   63.41 -        if (sb.toString().endsWith(".0")) {
   63.42 -            final int l = sb.length();
   63.43 -            sb.delete(l - 2, l);
   63.44 -        }
   63.45 -        return sb.toString().toString();
   63.46 -    }
   63.47 -    
   63.48 -    @Compare public String nameOfStringClass() throws Exception {
   63.49 -        return Class.forName("java.lang.String").getName();
   63.50 -    }
   63.51 -    @Compare public String nameOfArrayClass() throws Exception {
   63.52 -        return Class.forName("org.apidesign.vm4brwsr.Array").getName();
   63.53 -    }
   63.54 -    
   63.55 -    @Compare public String lowerHello() {
   63.56 -        return "HeLlO".toLowerCase();
   63.57 -    }
   63.58 -    
   63.59 -    @Compare public String lowerA() {
   63.60 -        return String.valueOf(Character.toLowerCase('A')).toString();
   63.61 -    }
   63.62 -    @Compare public String upperHello() {
   63.63 -        return "hello".toUpperCase();
   63.64 -    }
   63.65 -    
   63.66 -    @Compare public String upperA() {
   63.67 -        return String.valueOf(Character.toUpperCase('a')).toString();
   63.68 -    }
   63.69 -    
   63.70 -    @Compare public boolean matchRegExp() throws Exception {
   63.71 -        return "58038503".matches("\\d*");
   63.72 -    }
   63.73 -
   63.74 -    @Compare public boolean doesNotMatchRegExp() throws Exception {
   63.75 -        return "58038503GH".matches("\\d*");
   63.76 -    }
   63.77 -
   63.78 -    @Compare public boolean doesNotMatchRegExpFully() throws Exception {
   63.79 -        return "Hello".matches("Hell");
   63.80 -    }
   63.81 -    
   63.82 -    @Compare public String variousCharacterTests() throws Exception {
   63.83 -        StringBuilder sb = new StringBuilder();
   63.84 -        
   63.85 -        sb.append(Character.isUpperCase('a'));
   63.86 -        sb.append(Character.isUpperCase('A'));
   63.87 -        sb.append(Character.isLowerCase('a'));
   63.88 -        sb.append(Character.isLowerCase('A'));
   63.89 -        
   63.90 -        sb.append(Character.isLetter('A'));
   63.91 -        sb.append(Character.isLetterOrDigit('9'));
   63.92 -        sb.append(Character.isLetterOrDigit('A'));
   63.93 -        sb.append(Character.isLetter('0'));
   63.94 -        
   63.95 -        return sb.toString().toString();
   63.96 -    }
   63.97 -        
   63.98 -    @Compare
   63.99 -    public String nullFieldInitialized() {
  63.100 -        NullField nf = new NullField();
  63.101 -        return ("" + nf.name).toString();
  63.102 -    }
  63.103 -
  63.104 -    @Factory
  63.105 -    public static Object[] create() {
  63.106 -        return CompareVMs.create(CompareStringsTest.class);
  63.107 -    }
  63.108 -
  63.109 -    private static final class NullField {
  63.110 -
  63.111 -        String name;
  63.112 -    }
  63.113 -}
    64.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/tck/IntegerArithmeticTest.java	Fri Jan 11 16:07:55 2013 +0100
    64.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.3 @@ -1,98 +0,0 @@
    64.4 -/**
    64.5 - * Back 2 Browser Bytecode Translator
    64.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    64.7 - *
    64.8 - * This program is free software: you can redistribute it and/or modify
    64.9 - * it under the terms of the GNU General Public License as published by
   64.10 - * the Free Software Foundation, version 2 of the License.
   64.11 - *
   64.12 - * This program is distributed in the hope that it will be useful,
   64.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   64.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   64.15 - * GNU General Public License for more details.
   64.16 - *
   64.17 - * You should have received a copy of the GNU General Public License
   64.18 - * along with this program. Look for COPYING file in the top folder.
   64.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   64.20 - */
   64.21 -package org.apidesign.vm4brwsr.tck;
   64.22 -
   64.23 -import org.apidesign.vm4brwsr.Compare;
   64.24 -import org.apidesign.vm4brwsr.CompareVMs;
   64.25 -import org.testng.annotations.Factory;
   64.26 -
   64.27 -/**
   64.28 - *
   64.29 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   64.30 - */
   64.31 -public class IntegerArithmeticTest {
   64.32 -    
   64.33 -    private static int add(int x, int y) {
   64.34 -        return x + y;
   64.35 -    }
   64.36 -    
   64.37 -    private static int sub(int x, int y) {
   64.38 -        return x - y;
   64.39 -    }
   64.40 -    
   64.41 -    private static int mul(int x, int y) {
   64.42 -        return x * y;
   64.43 -    }
   64.44 -    
   64.45 -    private static int div(int x, int y) {
   64.46 -        return x / y;
   64.47 -    }
   64.48 -    
   64.49 -    private static int mod(int x, int y) {
   64.50 -        return x % y;
   64.51 -    }
   64.52 -    
   64.53 -    @Compare public int addOverflow() {
   64.54 -        return add(Integer.MAX_VALUE, 1);
   64.55 -    }
   64.56 -    
   64.57 -    @Compare public int subUnderflow() {
   64.58 -        return sub(Integer.MIN_VALUE, 1);
   64.59 -    }
   64.60 -    
   64.61 -    @Compare public int addMaxIntAndMaxInt() {
   64.62 -        return add(Integer.MAX_VALUE, Integer.MAX_VALUE);
   64.63 -    }
   64.64 -    
   64.65 -    @Compare public int subMinIntAndMinInt() {
   64.66 -        return sub(Integer.MIN_VALUE, Integer.MIN_VALUE);
   64.67 -    }
   64.68 -    
   64.69 -    @Compare public int multiplyMaxInt() {
   64.70 -        return mul(Integer.MAX_VALUE, 2);
   64.71 -    }
   64.72 -    
   64.73 -    @Compare public int multiplyMaxIntAndMaxInt() {
   64.74 -        return mul(Integer.MAX_VALUE, Integer.MAX_VALUE);
   64.75 -    }
   64.76 -    
   64.77 -    @Compare public int multiplyMinInt() {
   64.78 -        return mul(Integer.MIN_VALUE, 2);
   64.79 -    }
   64.80 -    
   64.81 -    @Compare public int multiplyMinIntAndMinInt() {
   64.82 -        return mul(Integer.MIN_VALUE, Integer.MIN_VALUE);
   64.83 -    }
   64.84 -    
   64.85 -    @Compare public int multiplyPrecision() {
   64.86 -        return mul(119106029, 1103515245);
   64.87 -    }
   64.88 -    
   64.89 -    @Compare public int division() {
   64.90 -        return div(1, 2);
   64.91 -    }
   64.92 -    
   64.93 -    @Compare public int divisionReminder() {
   64.94 -        return mod(1, 2);
   64.95 -    }
   64.96 -    
   64.97 -    @Factory
   64.98 -    public static Object[] create() {
   64.99 -        return CompareVMs.create(IntegerArithmeticTest.class);
  64.100 -    }
  64.101 -}
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/vmtest/pom.xml	Fri Jan 11 16:36:28 2013 +0100
    65.3 @@ -0,0 +1,61 @@
    65.4 +<?xml version="1.0"?>
    65.5 +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    65.6 +    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    65.7 +  <modelVersion>4.0.0</modelVersion>
    65.8 +  <parent>
    65.9 +    <groupId>org.apidesign</groupId>
   65.10 +    <artifactId>bck2brwsr</artifactId>
   65.11 +    <version>0.3-SNAPSHOT</version>
   65.12 +  </parent>
   65.13 +  <groupId>org.apidesign.bck2brwsr</groupId>
   65.14 +  <artifactId>vmtest</artifactId>
   65.15 +  <version>0.3-SNAPSHOT</version>
   65.16 +  
   65.17 +  <name>VM Testing APIs</name>
   65.18 +  <url>http://bck2brwsr.apidesign.org</url>
   65.19 +    <build>
   65.20 +        <plugins>
   65.21 +            <plugin>
   65.22 +                <groupId>org.apache.maven.plugins</groupId>
   65.23 +                <artifactId>maven-compiler-plugin</artifactId>
   65.24 +                <version>2.3.2</version>
   65.25 +                <configuration>
   65.26 +                    <source>1.7</source>
   65.27 +                    <target>1.7</target>
   65.28 +                </configuration>
   65.29 +            </plugin>
   65.30 +        </plugins>
   65.31 +    </build>
   65.32 +    <properties>
   65.33 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   65.34 +  </properties>
   65.35 +  <dependencies>
   65.36 +    <dependency>
   65.37 +      <groupId>org.testng</groupId>
   65.38 +      <artifactId>testng</artifactId>
   65.39 +      <scope>compile</scope>
   65.40 +      <exclusions>
   65.41 +        <exclusion>
   65.42 +          <artifactId>junit</artifactId>
   65.43 +          <groupId>junit</groupId>
   65.44 +        </exclusion>
   65.45 +      </exclusions>
   65.46 +    </dependency>
   65.47 +    <dependency>
   65.48 +      <groupId>${project.groupId}</groupId>
   65.49 +      <artifactId>vm4brwsr</artifactId>
   65.50 +      <version>0.3-SNAPSHOT</version>
   65.51 +      <type>jar</type>
   65.52 +    </dependency>
   65.53 +    <dependency>
   65.54 +      <groupId>${project.groupId}</groupId>
   65.55 +      <artifactId>emul</artifactId>
   65.56 +      <version>0.3-SNAPSHOT</version>
   65.57 +    </dependency>
   65.58 +    <dependency>
   65.59 +      <groupId>${project.groupId}</groupId>
   65.60 +      <artifactId>launcher</artifactId>
   65.61 +      <version>${project.version}</version>
   65.62 +    </dependency>
   65.63 +  </dependencies>
   65.64 +</project>
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/Compare.java	Fri Jan 11 16:36:28 2013 +0100
    66.3 @@ -0,0 +1,36 @@
    66.4 +/**
    66.5 + * Back 2 Browser Bytecode Translator
    66.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    66.7 + *
    66.8 + * This program is free software: you can redistribute it and/or modify
    66.9 + * it under the terms of the GNU General Public License as published by
   66.10 + * the Free Software Foundation, version 2 of the License.
   66.11 + *
   66.12 + * This program is distributed in the hope that it will be useful,
   66.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   66.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   66.15 + * GNU General Public License for more details.
   66.16 + *
   66.17 + * You should have received a copy of the GNU General Public License
   66.18 + * along with this program. Look for COPYING file in the top folder.
   66.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   66.20 + */
   66.21 +package org.apidesign.bck2brwsr.vmtest;
   66.22 +
   66.23 +import java.lang.annotation.ElementType;
   66.24 +import java.lang.annotation.Retention;
   66.25 +import java.lang.annotation.RetentionPolicy;
   66.26 +import java.lang.annotation.Target;
   66.27 +
   66.28 +/** Can be applied on a method that yields a return value. 
   66.29 + * Together with {@link VMTest#create} it can be used to write
   66.30 + * methods which are executed in real as well as JavaScript VMs and
   66.31 + * their results are compared.
   66.32 + *
   66.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   66.34 + */
   66.35 +@Retention(RetentionPolicy.RUNTIME)
   66.36 +@Target(ElementType.METHOD)
   66.37 +public @interface Compare {
   66.38 +    
   66.39 +}
    67.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/VMTest.java	Fri Jan 11 16:36:28 2013 +0100
    67.3 @@ -0,0 +1,43 @@
    67.4 +/**
    67.5 + * Back 2 Browser Bytecode Translator
    67.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    67.7 + *
    67.8 + * This program is free software: you can redistribute it and/or modify
    67.9 + * it under the terms of the GNU General Public License as published by
   67.10 + * the Free Software Foundation, version 2 of the License.
   67.11 + *
   67.12 + * This program is distributed in the hope that it will be useful,
   67.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   67.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   67.15 + * GNU General Public License for more details.
   67.16 + *
   67.17 + * You should have received a copy of the GNU General Public License
   67.18 + * along with this program. Look for COPYING file in the top folder.
   67.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   67.20 + */
   67.21 +package org.apidesign.bck2brwsr.vmtest;
   67.22 +
   67.23 +import org.apidesign.bck2brwsr.vmtest.impl.CompareCase;
   67.24 +import org.testng.annotations.Factory;
   67.25 +
   67.26 +/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
   67.27 + * in provided class and builds set of tests that compare the computations
   67.28 + * in real as well as JavaScript virtual machines. Use as:<pre>
   67.29 + * {@code @}{@link Factory} public static create() {
   67.30 + *   return @{link VMTest}.{@link #create(YourClass.class);
   67.31 + * }</pre>
   67.32 + *
   67.33 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   67.34 + */
   67.35 +public final class VMTest {
   67.36 +    /** Inspects <code>clazz</code> and for each {@lik Compare} method creates
   67.37 +     * instances of tests. Each instance runs the test in different virtual
   67.38 +     * machine and at the end they compare the results.
   67.39 +     * 
   67.40 +     * @param clazz the class to inspect
   67.41 +     * @return the set of created tests
   67.42 +     */
   67.43 +    public static Object[] create(Class<?> clazz) {
   67.44 +        return CompareCase.create(clazz);
   67.45 +    }
   67.46 +}
    68.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java	Fri Jan 11 16:36:28 2013 +0100
    68.3 @@ -0,0 +1,80 @@
    68.4 +/**
    68.5 + * Back 2 Browser Bytecode Translator
    68.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    68.7 + *
    68.8 + * This program is free software: you can redistribute it and/or modify
    68.9 + * it under the terms of the GNU General Public License as published by
   68.10 + * the Free Software Foundation, version 2 of the License.
   68.11 + *
   68.12 + * This program is distributed in the hope that it will be useful,
   68.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   68.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   68.15 + * GNU General Public License for more details.
   68.16 + *
   68.17 + * You should have received a copy of the GNU General Public License
   68.18 + * along with this program. Look for COPYING file in the top folder.
   68.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   68.20 + */
   68.21 +package org.apidesign.bck2brwsr.vmtest.impl;
   68.22 +
   68.23 +import java.io.File;
   68.24 +import java.io.FileWriter;
   68.25 +import java.io.IOException;
   68.26 +import java.lang.reflect.InvocationTargetException;
   68.27 +import java.lang.reflect.Method;
   68.28 +import java.util.Map;
   68.29 +import java.util.WeakHashMap;
   68.30 +import org.apidesign.bck2brwsr.launcher.Launcher;
   68.31 +import org.apidesign.bck2brwsr.launcher.MethodInvocation;
   68.32 +import org.testng.ITest;
   68.33 +import org.testng.annotations.Test;
   68.34 +
   68.35 +/**
   68.36 + *
   68.37 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   68.38 + */
   68.39 +public final class Bck2BrwsrCase implements ITest {
   68.40 +    private final Method m;
   68.41 +    private final Launcher l;
   68.42 +    private final String type;
   68.43 +    Object value;
   68.44 +    private static final Map<Class, Object[]> compiled = new WeakHashMap<>();
   68.45 +    private Object inst;
   68.46 +
   68.47 +    Bck2BrwsrCase(Method m, String type, Launcher l) {
   68.48 +        this.l = l;
   68.49 +        this.m = m;
   68.50 +        this.type = type;
   68.51 +    }
   68.52 +
   68.53 +    @Test(groups = "run")
   68.54 +    public void executeCode() throws Throwable {
   68.55 +        if (l != null) {
   68.56 +            MethodInvocation c = l.invokeMethod(m.getDeclaringClass(), m.getName());
   68.57 +            value = c.toString();
   68.58 +        } else {
   68.59 +            try {
   68.60 +                value = m.invoke(m.getDeclaringClass().newInstance());
   68.61 +            } catch (InvocationTargetException ex) {
   68.62 +                Throwable t = ex.getTargetException();
   68.63 +                value = t.getClass().getName() + ":" + t.getMessage();
   68.64 +            }
   68.65 +        }
   68.66 +    }
   68.67 +
   68.68 +    @Override
   68.69 +    public String getTestName() {
   68.70 +        return m.getName() + "[" + typeName() + "]";
   68.71 +    }
   68.72 +
   68.73 +    final String typeName() {
   68.74 +        return type;
   68.75 +    }
   68.76 +    static void dumpJS(StringBuilder sb, Bck2BrwsrCase c) throws IOException {
   68.77 +        File f = File.createTempFile(c.m.getName(), ".js");
   68.78 +        try (final FileWriter w = new FileWriter(f)) {
   68.79 +            w.append(c.l.toString());
   68.80 +        }
   68.81 +        sb.append("Path: ").append(f.getPath());
   68.82 +    }
   68.83 +}
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java	Fri Jan 11 16:36:28 2013 +0100
    69.3 @@ -0,0 +1,126 @@
    69.4 +/**
    69.5 + * Back 2 Browser Bytecode Translator
    69.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    69.7 + *
    69.8 + * This program is free software: you can redistribute it and/or modify
    69.9 + * it under the terms of the GNU General Public License as published by
   69.10 + * the Free Software Foundation, version 2 of the License.
   69.11 + *
   69.12 + * This program is distributed in the hope that it will be useful,
   69.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   69.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   69.15 + * GNU General Public License for more details.
   69.16 + *
   69.17 + * You should have received a copy of the GNU General Public License
   69.18 + * along with this program. Look for COPYING file in the top folder.
   69.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   69.20 + */
   69.21 +package org.apidesign.bck2brwsr.vmtest.impl;
   69.22 +
   69.23 +import org.apidesign.bck2brwsr.vmtest.*;
   69.24 +import java.io.File;
   69.25 +import java.io.FileWriter;
   69.26 +import java.io.IOException;
   69.27 +import java.lang.reflect.Method;
   69.28 +import java.util.ArrayList;
   69.29 +import java.util.List;
   69.30 +import org.apidesign.bck2brwsr.launcher.Launcher;
   69.31 +import org.testng.Assert;
   69.32 +import org.testng.ITest;
   69.33 +import org.testng.annotations.Factory;
   69.34 +import org.testng.annotations.Test;
   69.35 +
   69.36 +/** A TestNG {@link Factory} that seeks for {@link Compare} annotations
   69.37 + * in provided class and builds set of tests that compare the computations
   69.38 + * in real as well as JavaScript virtual machines. Use as:<pre>
   69.39 + * {@code @}{@link Factory} public static create() {
   69.40 + *   return @{link VMTest}.{@link #create(YourClass.class);
   69.41 + * }</pre>
   69.42 + *
   69.43 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   69.44 + */
   69.45 +public final class CompareCase implements ITest {
   69.46 +    private final Bck2BrwsrCase first, second;
   69.47 +    private final Method m;
   69.48 +    
   69.49 +    private CompareCase(Method m, Bck2BrwsrCase first, Bck2BrwsrCase second) {
   69.50 +        this.first = first;
   69.51 +        this.second = second;
   69.52 +        this.m = m;
   69.53 +    }
   69.54 +
   69.55 +    /** Inspects <code>clazz</code> and for each {@lik Compare} method creates
   69.56 +     * instances of tests. Each instance runs the test in different virtual
   69.57 +     * machine and at the end they compare the results.
   69.58 +     * 
   69.59 +     * @param clazz the class to inspect
   69.60 +     * @return the set of created tests
   69.61 +     */
   69.62 +    public static Object[] create(Class<?> clazz) {
   69.63 +        Method[] arr = clazz.getMethods();
   69.64 +        List<Object> ret = new ArrayList<>();
   69.65 +        
   69.66 +        final LaunchSetup l = LaunchSetup.INSTANCE;
   69.67 +        ret.add(l);
   69.68 +        
   69.69 +        String[] brwsr;
   69.70 +        {
   69.71 +            String p = System.getProperty("vmtest.brwsrs");
   69.72 +            if (p != null) {
   69.73 +                brwsr = p.split(",");
   69.74 +            } else {
   69.75 +                brwsr = new String[0];
   69.76 +            }
   69.77 +        }
   69.78 +        
   69.79 +        for (Method m : arr) {
   69.80 +            Compare c = m.getAnnotation(Compare.class);
   69.81 +            if (c == null) {
   69.82 +                continue;
   69.83 +            }
   69.84 +            final Bck2BrwsrCase real = new Bck2BrwsrCase(m, "Java", null);
   69.85 +            final Bck2BrwsrCase js = new Bck2BrwsrCase(m, "JavaScript", l.javaScript());
   69.86 +            ret.add(real);
   69.87 +            ret.add(js);
   69.88 +            ret.add(new CompareCase(m, real, js));
   69.89 +
   69.90 +            for (String b : brwsr) {
   69.91 +                final Launcher s = l.brwsr(b);
   69.92 +                ret.add(s);
   69.93 +                final Bck2BrwsrCase cse = new Bck2BrwsrCase(m, b, s);
   69.94 +                ret.add(cse);
   69.95 +                ret.add(new CompareCase(m, real, cse));
   69.96 +            }
   69.97 +        }
   69.98 +        return ret.toArray();
   69.99 +    }
  69.100 +
  69.101 +    /** Test that compares the previous results.
  69.102 +     * @throws Throwable 
  69.103 +     */
  69.104 +    @Test(dependsOnGroups = "run") public void compareResults() throws Throwable {
  69.105 +        Object v1 = first.value;
  69.106 +        Object v2 = second.value;
  69.107 +        if (v1 != null) {
  69.108 +            v1 = v1.toString();
  69.109 +        } else {
  69.110 +            v1 = "null";
  69.111 +        }
  69.112 +        try {
  69.113 +            Assert.assertEquals(v2, v1, "Comparing results");
  69.114 +        } catch (AssertionError e) {
  69.115 +            StringBuilder sb = new StringBuilder();
  69.116 +            sb.append(e.getMessage());
  69.117 +            Bck2BrwsrCase.dumpJS(sb, second);
  69.118 +            throw new AssertionError(sb.toString());
  69.119 +        }
  69.120 +    }
  69.121 +    
  69.122 +    /** Test name.
  69.123 +     * @return name of the tested method followed by a suffix
  69.124 +     */
  69.125 +    @Override
  69.126 +    public String getTestName() {
  69.127 +        return m.getName() + "[Compare " + second.typeName() + "]";
  69.128 +    }
  69.129 +}
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/LaunchSetup.java	Fri Jan 11 16:36:28 2013 +0100
    70.3 @@ -0,0 +1,68 @@
    70.4 +/**
    70.5 + * Back 2 Browser Bytecode Translator
    70.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    70.7 + *
    70.8 + * This program is free software: you can redistribute it and/or modify
    70.9 + * it under the terms of the GNU General Public License as published by
   70.10 + * the Free Software Foundation, version 2 of the License.
   70.11 + *
   70.12 + * This program is distributed in the hope that it will be useful,
   70.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   70.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   70.15 + * GNU General Public License for more details.
   70.16 + *
   70.17 + * You should have received a copy of the GNU General Public License
   70.18 + * along with this program. Look for COPYING file in the top folder.
   70.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   70.20 + */
   70.21 +package org.apidesign.bck2brwsr.vmtest.impl;
   70.22 +
   70.23 +import java.io.IOException;
   70.24 +import java.util.LinkedHashMap;
   70.25 +import java.util.Map;
   70.26 +import org.apidesign.bck2brwsr.launcher.Launcher;
   70.27 +import org.testng.annotations.AfterGroups;
   70.28 +import org.testng.annotations.BeforeGroups;
   70.29 +
   70.30 +/**
   70.31 + *
   70.32 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   70.33 + */
   70.34 +public final class LaunchSetup {
   70.35 +    static LaunchSetup INSTANCE = new LaunchSetup();
   70.36 +    
   70.37 +    private final Launcher js = Launcher.createJavaScript();
   70.38 +    private final Map<String,Launcher> brwsrs = new LinkedHashMap<>();
   70.39 +    
   70.40 +    private LaunchSetup() {
   70.41 +    }
   70.42 +    
   70.43 +    public  Launcher javaScript() {
   70.44 +        return js;
   70.45 +    } 
   70.46 +    
   70.47 +    public synchronized Launcher brwsr(String cmd) {
   70.48 +        Launcher s = brwsrs.get(cmd);
   70.49 +        if (s == null) {
   70.50 +            s = Launcher.createBrowser(cmd);
   70.51 +            brwsrs.put(cmd, s);
   70.52 +        }
   70.53 +        return s;
   70.54 +    }
   70.55 +
   70.56 +    @BeforeGroups("run")
   70.57 +    public void initializeLauncher() throws IOException {
   70.58 +        js.initialize();
   70.59 +        for (Launcher launcher : brwsrs.values()) {
   70.60 +            launcher.initialize();
   70.61 +        }
   70.62 +    }
   70.63 +
   70.64 +    @AfterGroups("run")
   70.65 +    public void shutDownLauncher() throws IOException, InterruptedException {
   70.66 +        js.shutdown();
   70.67 +        for (Launcher launcher : brwsrs.values()) {
   70.68 +            launcher.shutdown();
   70.69 +        }
   70.70 +    }
   70.71 +}
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CloneTest.java	Fri Jan 11 16:36:28 2013 +0100
    71.3 @@ -0,0 +1,73 @@
    71.4 +/**
    71.5 + * Back 2 Browser Bytecode Translator
    71.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    71.7 + *
    71.8 + * This program is free software: you can redistribute it and/or modify
    71.9 + * it under the terms of the GNU General Public License as published by
   71.10 + * the Free Software Foundation, version 2 of the License.
   71.11 + *
   71.12 + * This program is distributed in the hope that it will be useful,
   71.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   71.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   71.15 + * GNU General Public License for more details.
   71.16 + *
   71.17 + * You should have received a copy of the GNU General Public License
   71.18 + * along with this program. Look for COPYING file in the top folder.
   71.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   71.20 + */
   71.21 +package org.apidesign.bck2brwsr.tck;
   71.22 +
   71.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   71.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   71.25 +import org.testng.annotations.Factory;
   71.26 +
   71.27 +/**
   71.28 + *
   71.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   71.30 + */
   71.31 +public class CloneTest {
   71.32 +    private int value;
   71.33 +    
   71.34 +    @Compare
   71.35 +    public Object notSupported() throws CloneNotSupportedException {
   71.36 +        return this.clone();
   71.37 +    }
   71.38 +
   71.39 +    @Compare public String sameClass() throws CloneNotSupportedException {
   71.40 +        return new Clnbl().clone().getClass().getName();
   71.41 +    }
   71.42 +
   71.43 +    @Compare public boolean differentInstance() throws CloneNotSupportedException {
   71.44 +        Clnbl orig = new Clnbl();
   71.45 +        return orig == orig.clone();
   71.46 +    }
   71.47 +
   71.48 +    @Compare public int sameReference() throws CloneNotSupportedException {
   71.49 +        CloneTest self = this;
   71.50 +        Clnbl orig = new Clnbl();
   71.51 +        self.value = 33;
   71.52 +        orig.ref = self;
   71.53 +        return ((Clnbl)orig.clone()).ref.value;
   71.54 +    }
   71.55 +
   71.56 +    @Compare public int sameValue() throws CloneNotSupportedException {
   71.57 +        Clnbl orig = new Clnbl();
   71.58 +        orig.value = 10;
   71.59 +        return ((Clnbl)orig.clone()).value;
   71.60 +    }
   71.61 +    
   71.62 +    @Factory
   71.63 +    public static Object[] create() {
   71.64 +        return VMTest.create(CloneTest.class);
   71.65 +    }
   71.66 +    
   71.67 +    public static final class Clnbl implements Cloneable {
   71.68 +        public CloneTest ref;
   71.69 +        private int value;
   71.70 +
   71.71 +        @Override
   71.72 +        public Object clone() throws CloneNotSupportedException {
   71.73 +            return super.clone();
   71.74 +        }
   71.75 +    }
   71.76 +}
    72.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareByteArrayTest.java	Fri Jan 11 16:36:28 2013 +0100
    72.3 @@ -0,0 +1,63 @@
    72.4 +/**
    72.5 + * Back 2 Browser Bytecode Translator
    72.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    72.7 + *
    72.8 + * This program is free software: you can redistribute it and/or modify
    72.9 + * it under the terms of the GNU General Public License as published by
   72.10 + * the Free Software Foundation, version 2 of the License.
   72.11 + *
   72.12 + * This program is distributed in the hope that it will be useful,
   72.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   72.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   72.15 + * GNU General Public License for more details.
   72.16 + *
   72.17 + * You should have received a copy of the GNU General Public License
   72.18 + * along with this program. Look for COPYING file in the top folder.
   72.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   72.20 + */
   72.21 +package org.apidesign.bck2brwsr.tck;
   72.22 +
   72.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   72.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   72.25 +import org.testng.annotations.Factory;
   72.26 +
   72.27 +/**
   72.28 + *
   72.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   72.30 + */
   72.31 +public class CompareByteArrayTest {
   72.32 +    @Compare public int byteArraySum() {
   72.33 +        byte[] arr = createArray();
   72.34 +        return sumByteArr(arr);
   72.35 +    }
   72.36 +    
   72.37 +    @Compare public int countZeros() {
   72.38 +        int zeros = 0;
   72.39 +        for (Byte b : createArray()) {
   72.40 +            if (b == 0) {
   72.41 +                zeros++;
   72.42 +            }
   72.43 +        }
   72.44 +        return zeros;
   72.45 +    }
   72.46 +    
   72.47 +    private static int sumByteArr(byte[] arr) {
   72.48 +        int sum = 0;
   72.49 +        for (int i = 0; i < arr.length; i++) {
   72.50 +            sum += arr[i];
   72.51 +        }
   72.52 +        return sum;
   72.53 +    }
   72.54 +    
   72.55 +    @Factory
   72.56 +    public static Object[] create() {
   72.57 +        return VMTest.create(CompareByteArrayTest.class);
   72.58 +    }
   72.59 +
   72.60 +    private byte[] createArray() {
   72.61 +        byte[] arr = new byte[10];
   72.62 +        arr[5] = 3;
   72.63 +        arr[7] = 8;
   72.64 +        return arr;
   72.65 +    }
   72.66 +}
    73.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareHashTest.java	Fri Jan 11 16:36:28 2013 +0100
    73.3 @@ -0,0 +1,46 @@
    73.4 +/**
    73.5 + * Back 2 Browser Bytecode Translator
    73.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    73.7 + *
    73.8 + * This program is free software: you can redistribute it and/or modify
    73.9 + * it under the terms of the GNU General Public License as published by
   73.10 + * the Free Software Foundation, version 2 of the License.
   73.11 + *
   73.12 + * This program is distributed in the hope that it will be useful,
   73.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   73.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   73.15 + * GNU General Public License for more details.
   73.16 + *
   73.17 + * You should have received a copy of the GNU General Public License
   73.18 + * along with this program. Look for COPYING file in the top folder.
   73.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   73.20 + */
   73.21 +package org.apidesign.bck2brwsr.tck;
   73.22 +
   73.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   73.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   73.25 +import org.testng.annotations.Factory;
   73.26 +
   73.27 +/**
   73.28 + *
   73.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   73.30 + */
   73.31 +public class CompareHashTest {
   73.32 +    @Compare public int hashOfString() {
   73.33 +        return "Ahoj".hashCode();
   73.34 +    }
   73.35 +    
   73.36 +    @Compare public int hashRemainsYieldsZero() {
   73.37 +        Object o = new Object();
   73.38 +        return o.hashCode() - o.hashCode();
   73.39 +    }
   73.40 +    
   73.41 +    @Compare public int hashOfInt() {
   73.42 +        return Integer.valueOf(Integer.MAX_VALUE).hashCode();
   73.43 +    }
   73.44 +    
   73.45 +    @Factory
   73.46 +    public static Object[] create() {
   73.47 +        return VMTest.create(CompareHashTest.class);
   73.48 +    }
   73.49 +}
    74.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareIntArrayTest.java	Fri Jan 11 16:36:28 2013 +0100
    74.3 @@ -0,0 +1,63 @@
    74.4 +/**
    74.5 + * Back 2 Browser Bytecode Translator
    74.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    74.7 + *
    74.8 + * This program is free software: you can redistribute it and/or modify
    74.9 + * it under the terms of the GNU General Public License as published by
   74.10 + * the Free Software Foundation, version 2 of the License.
   74.11 + *
   74.12 + * This program is distributed in the hope that it will be useful,
   74.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   74.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   74.15 + * GNU General Public License for more details.
   74.16 + *
   74.17 + * You should have received a copy of the GNU General Public License
   74.18 + * along with this program. Look for COPYING file in the top folder.
   74.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   74.20 + */
   74.21 +package org.apidesign.bck2brwsr.tck;
   74.22 +
   74.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   74.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   74.25 +import org.testng.annotations.Factory;
   74.26 +
   74.27 +/**
   74.28 + *
   74.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   74.30 + */
   74.31 +public class CompareIntArrayTest {
   74.32 +    @Compare public int integerArraySum() {
   74.33 +        int[] arr = createArray();
   74.34 +        return sumIntArr(arr);
   74.35 +    }
   74.36 +    
   74.37 +    @Compare public int countZeros() {
   74.38 +        int zeros = 0;
   74.39 +        for (Integer i : createArray()) {
   74.40 +            if (i == 0) {
   74.41 +                zeros++;
   74.42 +            }
   74.43 +        }
   74.44 +        return zeros;
   74.45 +    }
   74.46 +    
   74.47 +    private static int sumIntArr(int[] arr) {
   74.48 +        int sum = 0;
   74.49 +        for (int i = 0; i < arr.length; i++) {
   74.50 +            sum += arr[i];
   74.51 +        }
   74.52 +        return sum;
   74.53 +    }
   74.54 +    
   74.55 +    @Factory
   74.56 +    public static Object[] create() {
   74.57 +        return VMTest.create(CompareIntArrayTest.class);
   74.58 +    }
   74.59 +
   74.60 +    private int[] createArray() {
   74.61 +        int[] arr = new int[10];
   74.62 +        arr[5] = 3;
   74.63 +        arr[7] = 8;
   74.64 +        return arr;
   74.65 +    }
   74.66 +}
    75.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/CompareStringsTest.java	Fri Jan 11 16:36:28 2013 +0100
    75.3 @@ -0,0 +1,110 @@
    75.4 +/**
    75.5 + * Back 2 Browser Bytecode Translator
    75.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    75.7 + *
    75.8 + * This program is free software: you can redistribute it and/or modify
    75.9 + * it under the terms of the GNU General Public License as published by
   75.10 + * the Free Software Foundation, version 2 of the License.
   75.11 + *
   75.12 + * This program is distributed in the hope that it will be useful,
   75.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   75.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   75.15 + * GNU General Public License for more details.
   75.16 + *
   75.17 + * You should have received a copy of the GNU General Public License
   75.18 + * along with this program. Look for COPYING file in the top folder.
   75.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   75.20 + */
   75.21 +package org.apidesign.bck2brwsr.tck;
   75.22 +
   75.23 +import java.net.MalformedURLException;
   75.24 +import java.net.URL;
   75.25 +import org.apidesign.bck2brwsr.vmtest.Compare;
   75.26 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   75.27 +import org.testng.annotations.Factory;
   75.28 +
   75.29 +/**
   75.30 + *
   75.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   75.32 + */
   75.33 +public class CompareStringsTest {
   75.34 +    @Compare public static Object compareURLs() throws MalformedURLException {
   75.35 +        return new URL("http://apidesign.org:8080/wiki/").toExternalForm().toString();
   75.36 +    }
   75.37 +    
   75.38 +    @Compare public String deleteLastTwoCharacters() {
   75.39 +        StringBuilder sb = new StringBuilder();
   75.40 +        sb.append("453.0");
   75.41 +        if (sb.toString().endsWith(".0")) {
   75.42 +            final int l = sb.length();
   75.43 +            sb.delete(l - 2, l);
   75.44 +        }
   75.45 +        return sb.toString().toString();
   75.46 +    }
   75.47 +    
   75.48 +    @Compare public String nameOfStringClass() throws Exception {
   75.49 +        return Class.forName("java.lang.String").getName();
   75.50 +    }
   75.51 +    @Compare public String nameOfArrayClass() throws Exception {
   75.52 +        return Class.forName("org.apidesign.bck2brwsr.tck.CompareHashTest").getName();
   75.53 +    }
   75.54 +    
   75.55 +    @Compare public String lowerHello() {
   75.56 +        return "HeLlO".toLowerCase();
   75.57 +    }
   75.58 +    
   75.59 +    @Compare public String lowerA() {
   75.60 +        return String.valueOf(Character.toLowerCase('A')).toString();
   75.61 +    }
   75.62 +    @Compare public String upperHello() {
   75.63 +        return "hello".toUpperCase();
   75.64 +    }
   75.65 +    
   75.66 +    @Compare public String upperA() {
   75.67 +        return String.valueOf(Character.toUpperCase('a')).toString();
   75.68 +    }
   75.69 +    
   75.70 +    @Compare public boolean matchRegExp() throws Exception {
   75.71 +        return "58038503".matches("\\d*");
   75.72 +    }
   75.73 +
   75.74 +    @Compare public boolean doesNotMatchRegExp() throws Exception {
   75.75 +        return "58038503GH".matches("\\d*");
   75.76 +    }
   75.77 +
   75.78 +    @Compare public boolean doesNotMatchRegExpFully() throws Exception {
   75.79 +        return "Hello".matches("Hell");
   75.80 +    }
   75.81 +    
   75.82 +    @Compare public String variousCharacterTests() throws Exception {
   75.83 +        StringBuilder sb = new StringBuilder();
   75.84 +        
   75.85 +        sb.append(Character.isUpperCase('a'));
   75.86 +        sb.append(Character.isUpperCase('A'));
   75.87 +        sb.append(Character.isLowerCase('a'));
   75.88 +        sb.append(Character.isLowerCase('A'));
   75.89 +        
   75.90 +        sb.append(Character.isLetter('A'));
   75.91 +        sb.append(Character.isLetterOrDigit('9'));
   75.92 +        sb.append(Character.isLetterOrDigit('A'));
   75.93 +        sb.append(Character.isLetter('0'));
   75.94 +        
   75.95 +        return sb.toString().toString();
   75.96 +    }
   75.97 +        
   75.98 +    @Compare
   75.99 +    public String nullFieldInitialized() {
  75.100 +        NullField nf = new NullField();
  75.101 +        return ("" + nf.name).toString();
  75.102 +    }
  75.103 +
  75.104 +    @Factory
  75.105 +    public static Object[] create() {
  75.106 +        return VMTest.create(CompareStringsTest.class);
  75.107 +    }
  75.108 +
  75.109 +    private static final class NullField {
  75.110 +
  75.111 +        String name;
  75.112 +    }
  75.113 +}
    76.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/IntegerArithmeticTest.java	Fri Jan 11 16:36:28 2013 +0100
    76.3 @@ -0,0 +1,98 @@
    76.4 +/**
    76.5 + * Back 2 Browser Bytecode Translator
    76.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    76.7 + *
    76.8 + * This program is free software: you can redistribute it and/or modify
    76.9 + * it under the terms of the GNU General Public License as published by
   76.10 + * the Free Software Foundation, version 2 of the License.
   76.11 + *
   76.12 + * This program is distributed in the hope that it will be useful,
   76.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   76.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   76.15 + * GNU General Public License for more details.
   76.16 + *
   76.17 + * You should have received a copy of the GNU General Public License
   76.18 + * along with this program. Look for COPYING file in the top folder.
   76.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   76.20 + */
   76.21 +package org.apidesign.bck2brwsr.tck;
   76.22 +
   76.23 +import org.apidesign.bck2brwsr.vmtest.Compare;
   76.24 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   76.25 +import org.testng.annotations.Factory;
   76.26 +
   76.27 +/**
   76.28 + *
   76.29 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   76.30 + */
   76.31 +public class IntegerArithmeticTest {
   76.32 +    
   76.33 +    private static int add(int x, int y) {
   76.34 +        return x + y;
   76.35 +    }
   76.36 +    
   76.37 +    private static int sub(int x, int y) {
   76.38 +        return x - y;
   76.39 +    }
   76.40 +    
   76.41 +    private static int mul(int x, int y) {
   76.42 +        return x * y;
   76.43 +    }
   76.44 +    
   76.45 +    private static int div(int x, int y) {
   76.46 +        return x / y;
   76.47 +    }
   76.48 +    
   76.49 +    private static int mod(int x, int y) {
   76.50 +        return x % y;
   76.51 +    }
   76.52 +    
   76.53 +    @Compare public int addOverflow() {
   76.54 +        return add(Integer.MAX_VALUE, 1);
   76.55 +    }
   76.56 +    
   76.57 +    @Compare public int subUnderflow() {
   76.58 +        return sub(Integer.MIN_VALUE, 1);
   76.59 +    }
   76.60 +    
   76.61 +    @Compare public int addMaxIntAndMaxInt() {
   76.62 +        return add(Integer.MAX_VALUE, Integer.MAX_VALUE);
   76.63 +    }
   76.64 +    
   76.65 +    @Compare public int subMinIntAndMinInt() {
   76.66 +        return sub(Integer.MIN_VALUE, Integer.MIN_VALUE);
   76.67 +    }
   76.68 +    
   76.69 +    @Compare public int multiplyMaxInt() {
   76.70 +        return mul(Integer.MAX_VALUE, 2);
   76.71 +    }
   76.72 +    
   76.73 +    @Compare public int multiplyMaxIntAndMaxInt() {
   76.74 +        return mul(Integer.MAX_VALUE, Integer.MAX_VALUE);
   76.75 +    }
   76.76 +    
   76.77 +    @Compare public int multiplyMinInt() {
   76.78 +        return mul(Integer.MIN_VALUE, 2);
   76.79 +    }
   76.80 +    
   76.81 +    @Compare public int multiplyMinIntAndMinInt() {
   76.82 +        return mul(Integer.MIN_VALUE, Integer.MIN_VALUE);
   76.83 +    }
   76.84 +    
   76.85 +    @Compare public int multiplyPrecision() {
   76.86 +        return mul(119106029, 1103515245);
   76.87 +    }
   76.88 +    
   76.89 +    @Compare public int division() {
   76.90 +        return div(1, 2);
   76.91 +    }
   76.92 +    
   76.93 +    @Compare public int divisionReminder() {
   76.94 +        return mod(1, 2);
   76.95 +    }
   76.96 +    
   76.97 +    @Factory
   76.98 +    public static Object[] create() {
   76.99 +        return VMTest.create(IntegerArithmeticTest.class);
  76.100 +    }
  76.101 +}
    77.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ReflectionTest.java	Fri Jan 11 16:36:28 2013 +0100
    77.3 @@ -0,0 +1,105 @@
    77.4 +/**
    77.5 + * Back 2 Browser Bytecode Translator
    77.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    77.7 + *
    77.8 + * This program is free software: you can redistribute it and/or modify
    77.9 + * it under the terms of the GNU General Public License as published by
   77.10 + * the Free Software Foundation, version 2 of the License.
   77.11 + *
   77.12 + * This program is distributed in the hope that it will be useful,
   77.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   77.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   77.15 + * GNU General Public License for more details.
   77.16 + *
   77.17 + * You should have received a copy of the GNU General Public License
   77.18 + * along with this program. Look for COPYING file in the top folder.
   77.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   77.20 + */
   77.21 +package org.apidesign.bck2brwsr.tck;
   77.22 +
   77.23 +import java.lang.reflect.Method;
   77.24 +import java.util.Arrays;
   77.25 +import java.util.Collections;
   77.26 +import java.util.List;
   77.27 +import org.apidesign.bck2brwsr.core.JavaScriptBody;
   77.28 +import org.apidesign.bck2brwsr.vmtest.Compare;
   77.29 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   77.30 +import org.testng.annotations.Factory;
   77.31 +
   77.32 +/**
   77.33 + *
   77.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   77.35 + */
   77.36 +public class ReflectionTest {
   77.37 +    @Compare public boolean nonNullThis() {
   77.38 +        return this == null;
   77.39 +    }
   77.40 +    
   77.41 +    @Compare public String intType() {
   77.42 +        return Integer.TYPE.toString();
   77.43 +    }
   77.44 +
   77.45 +    @Compare public String voidType() throws Exception {
   77.46 +        return void.class.toString();
   77.47 +    }
   77.48 +
   77.49 +    @Compare public String longClass() {
   77.50 +        return long.class.toString();
   77.51 +    }
   77.52 +    
   77.53 +    @Compare public String namesOfMethods() {
   77.54 +        StringBuilder sb = new StringBuilder();
   77.55 +        String[] arr = new String[20];
   77.56 +        int i = 0;
   77.57 +        for (Method m : StaticUse.class.getMethods()) {
   77.58 +            arr[i++] = m.getName();
   77.59 +        }
   77.60 +        for (String s : sort(arr, i)) {
   77.61 +            sb.append(s).append("\n");
   77.62 +        }
   77.63 +        return sb.toString();
   77.64 +    }
   77.65 +    
   77.66 +    @Compare public String cannotCallNonStaticMethodWithNull() throws Exception {
   77.67 +        StaticUse.class.getMethod("instanceMethod").invoke(null);
   77.68 +        return "should not happen";
   77.69 +    }
   77.70 +
   77.71 +    @Compare public Object voidReturnType() throws Exception {
   77.72 +        return StaticUse.class.getMethod("instanceMethod").getReturnType();
   77.73 +    }
   77.74 +    
   77.75 +    @Compare public String newInstanceFails() throws InstantiationException {
   77.76 +        try {
   77.77 +            return "success: " + StaticUse.class.newInstance();
   77.78 +        } catch (IllegalAccessException ex) {
   77.79 +            return ex.getClass().getName();
   77.80 +        }
   77.81 +    }
   77.82 +    
   77.83 +    @Compare public String paramTypes() throws Exception {
   77.84 +        Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
   77.85 +        final Class[] pt = plus.getParameterTypes();
   77.86 +        return pt[0].getName();
   77.87 +    }
   77.88 +    @Compare public String paramTypesNotFound() throws Exception {
   77.89 +        return StaticUse.class.getMethod("plus", int.class, double.class).toString();
   77.90 +    }
   77.91 +    @Compare public int methodWithArgs() throws Exception {
   77.92 +        Method plus = StaticUse.class.getMethod("plus", int.class, Integer.TYPE);
   77.93 +        return (Integer)plus.invoke(null, 2, 3);
   77.94 +    }
   77.95 +    
   77.96 +    @JavaScriptBody(args = { "arr", "len" }, body="var a = arr.slice(0, len); a.sort(); return a;")
   77.97 +    private static String[] sort(String[] arr, int len) {
   77.98 +        List<String> list = Arrays.asList(arr).subList(0, len);
   77.99 +        Collections.sort(list);
  77.100 +        return list.toArray(new String[0]);
  77.101 +    }
  77.102 +    
  77.103 +    @Factory
  77.104 +    public static Object[] create() {
  77.105 +        return VMTest.create(ReflectionTest.class);
  77.106 +    }
  77.107 +    
  77.108 +}
    78.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/ResourcesTest.java	Fri Jan 11 16:36:28 2013 +0100
    78.3 @@ -0,0 +1,45 @@
    78.4 +/**
    78.5 + * Back 2 Browser Bytecode Translator
    78.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    78.7 + *
    78.8 + * This program is free software: you can redistribute it and/or modify
    78.9 + * it under the terms of the GNU General Public License as published by
   78.10 + * the Free Software Foundation, version 2 of the License.
   78.11 + *
   78.12 + * This program is distributed in the hope that it will be useful,
   78.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   78.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   78.15 + * GNU General Public License for more details.
   78.16 + *
   78.17 + * You should have received a copy of the GNU General Public License
   78.18 + * along with this program. Look for COPYING file in the top folder.
   78.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   78.20 + */
   78.21 +package org.apidesign.bck2brwsr.tck;
   78.22 +
   78.23 +import java.io.InputStream;
   78.24 +import org.apidesign.bck2brwsr.vmtest.Compare;
   78.25 +import org.apidesign.bck2brwsr.vmtest.VMTest;
   78.26 +import org.testng.annotations.Factory;
   78.27 +
   78.28 +/**
   78.29 + *
   78.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   78.31 + */
   78.32 +public class ResourcesTest {
   78.33 +    
   78.34 +    @Compare public String readResourceAsStream() throws Exception {
   78.35 +        InputStream is = getClass().getResourceAsStream("Resources.txt");
   78.36 +        byte[] b = new byte[30];
   78.37 +        int len = is.read(b);
   78.38 +        StringBuilder sb = new StringBuilder();
   78.39 +        for (int i = 0; i < len; i++) {
   78.40 +            sb.append((char)b[i]);
   78.41 +        }
   78.42 +        return sb.toString();
   78.43 +    }
   78.44 +    
   78.45 +    @Factory public static Object[] create() {
   78.46 +        return VMTest.create(ResourcesTest.class);
   78.47 +    }
   78.48 +}
    79.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.2 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/StaticUse.java	Fri Jan 11 16:36:28 2013 +0100
    79.3 @@ -0,0 +1,31 @@
    79.4 +/**
    79.5 + * Back 2 Browser Bytecode Translator
    79.6 + * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    79.7 + *
    79.8 + * This program is free software: you can redistribute it and/or modify
    79.9 + * it under the terms of the GNU General Public License as published by
   79.10 + * the Free Software Foundation, version 2 of the License.
   79.11 + *
   79.12 + * This program is distributed in the hope that it will be useful,
   79.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   79.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   79.15 + * GNU General Public License for more details.
   79.16 + *
   79.17 + * You should have received a copy of the GNU General Public License
   79.18 + * along with this program. Look for COPYING file in the top folder.
   79.19 + * If not, see http://opensource.org/licenses/GPL-2.0.
   79.20 + */
   79.21 +package org.apidesign.bck2brwsr.tck;
   79.22 +
   79.23 +class StaticUse {
   79.24 +    public static final Object NON_NULL = new Object();
   79.25 +    private StaticUse() {
   79.26 +    }
   79.27 +    
   79.28 +    public void instanceMethod() {
   79.29 +    }
   79.30 +
   79.31 +    public static int plus(int a, int b) {
   79.32 +        return a + b;
   79.33 +    }
   79.34 +}
    80.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.2 +++ b/vmtest/src/test/resources/org/apidesign/bck2brwsr/tck/Resources.txt	Fri Jan 11 16:36:28 2013 +0100
    80.3 @@ -0,0 +1,1 @@
    80.4 +Ahoj