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"> & </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"><jaroslav.tulach@apidesign.org></span>
31.101 + <span class="comment">*/</span>
31.102 + @Page(xhtml=<span class="string">"</span><span class="string">Calculator.xhtml</span><span class="string">"</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">"</span><span class="string">clear</span><span class="string">"</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">"</span><span class="string">0</span><span class="string">"</span>);
31.112 + }
31.113 +
31.114 + @OnClick(id= { <span class="string">"</span><span class="string">plus</span><span class="string">"</span>, <span class="string">"</span><span class="string">minus</span><span class="string">"</span>, <span class="string">"</span><span class="string">mul</span><span class="string">"</span>, <span class="string">"</span><span class="string">div</span><span class="string">"</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">"</span><span class="string">0</span><span class="string">"</span>);
31.119 + }
31.120 +
31.121 + @OnClick(id=<span class="string">"</span><span class="string">result</span><span class="string">"</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">"</span><span class="string">plus</span><span class="string">"</span>: setValue(memory + getValue()); <span class="keyword-directive">break</span>;
31.125 + <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">minus</span><span class="string">"</span>: setValue(memory - getValue()); <span class="keyword-directive">break</span>;
31.126 + <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">mul</span><span class="string">"</span>: setValue(memory * getValue()); <span class="keyword-directive">break</span>;
31.127 + <span class="keyword-directive">case</span> <span class="string">"</span><span class="string">div</span><span class="string">"</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">"</span><span class="string">n0</span><span class="string">"</span>, <span class="string">"</span><span class="string">n1</span><span class="string">"</span>, <span class="string">"</span><span class="string">n2</span><span class="string">"</span>, <span class="string">"</span><span class="string">n3</span><span class="string">"</span>, <span class="string">"</span><span class="string">n4</span><span class="string">"</span>, <span class="string">"</span><span class="string">n5</span><span class="string">"</span>, <span class="string">"</span><span class="string">n6</span><span class="string">"</span>, <span class="string">"</span><span class="string">n7</span><span class="string">"</span>, <span class="string">"</span><span class="string">n8</span><span class="string">"</span>, <span class="string">"</span><span class="string">n9</span><span class="string">"</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">"</span><span class="string">err</span><span class="string">"</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