1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/pom.xml Mon Aug 27 05:08:30 2012 +0200
1.3 @@ -0,0 +1,86 @@
1.4 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1.5 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
1.6 + <modelVersion>4.0.0</modelVersion>
1.7 +
1.8 + <groupId>org.apidesign</groupId>
1.9 + <artifactId>java4browser</artifactId>
1.10 + <version>0.1-SNAPSHOT</version>
1.11 + <packaging>jar</packaging>
1.12 +
1.13 + <name>java4browser</name>
1.14 + <url>http://java4browser.apidesign.org</url>
1.15 +
1.16 + <properties>
1.17 + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1.18 + <author.name>Jaroslav Tulach</author.name>
1.19 + <author.email>jaroslav.tulach@apidesign.org</author.email>
1.20 + </properties>
1.21 +
1.22 + <repositories>
1.23 + <repository>
1.24 + <id>netbeans</id>
1.25 + <name>NetBeans</name>
1.26 + <url>http://bits.netbeans.org/maven2/</url>
1.27 + </repository>
1.28 + </repositories>
1.29 + <pluginRepositories>
1.30 + <pluginRepository>
1.31 + <id>mc-release</id>
1.32 + <name>Local Maven repository of releases</name>
1.33 + <url>http://mc-repo.googlecode.com/svn/maven2/releases</url>
1.34 + <snapshots>
1.35 + <enabled>false</enabled>
1.36 + </snapshots>
1.37 + <releases>
1.38 + <enabled>true</enabled>
1.39 + </releases>
1.40 + </pluginRepository>
1.41 + </pluginRepositories>
1.42 + <scm>
1.43 + <connection>scm:hg:http://source.apidesign.org/hg/quoridor</connection>
1.44 + <url>http://source.apidesign.org/hg/quoridor</url>
1.45 + </scm>
1.46 + <licenses>
1.47 + <license>
1.48 + <name>GPL-2.0</name>
1.49 + <url>http://opensource.org/licenses/GPL-2.0</url>
1.50 + <distribution>repo</distribution>
1.51 + </license>
1.52 + </licenses>
1.53 + <organization>
1.54 + <name>API Design</name>
1.55 + <url>http://apidesign.org</url>
1.56 + </organization>
1.57 + <build>
1.58 + <plugins>
1.59 + <plugin>
1.60 + <groupId>com.mycila.maven-license-plugin</groupId>
1.61 + <artifactId>maven-license-plugin</artifactId>
1.62 + <version>1.9.0</version>
1.63 + <configuration>
1.64 + <header>src/header.txt</header>
1.65 + </configuration>
1.66 + </plugin>
1.67 + </plugins>
1.68 + </build>
1.69 + <dependencies>
1.70 + <dependency>
1.71 + <groupId>org.testng</groupId>
1.72 + <artifactId>testng</artifactId>
1.73 + <version>6.7</version>
1.74 + <scope>test</scope>
1.75 + <exclusions>
1.76 + <exclusion>
1.77 + <artifactId>junit</artifactId>
1.78 + <groupId>junit</groupId>
1.79 + </exclusion>
1.80 + </exclusions>
1.81 + </dependency>
1.82 + <dependency>
1.83 + <groupId>org.netbeans.api</groupId>
1.84 + <artifactId>org-netbeans-modules-classfile</artifactId>
1.85 + <version>RELEASE72</version>
1.86 + <type>jar</type>
1.87 + </dependency>
1.88 + </dependencies>
1.89 +</project>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/src/header.txt Mon Aug 27 05:08:30 2012 +0200
2.3 @@ -0,0 +1,15 @@
2.4 +Java 4 Browser Bytecode Translator
2.5 +Copyright (C) 2012-${year} Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.6 +
2.7 +This program is free software: you can redistribute it and/or modify
2.8 +it under the terms of the GNU General Public License as published by
2.9 +the Free Software Foundation, version 2 of the License.
2.10 +
2.11 +This program is distributed in the hope that it will be useful,
2.12 +but WITHOUT ANY WARRANTY; without even the implied warranty of
2.13 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.14 +GNU General Public License for more details.
2.15 +
2.16 +You should have received a copy of the GNU General Public License
2.17 +along with this program. Look for COPYING file in the top folder.
2.18 +If not, see http://opensource.org/licenses/GPL-2.0.
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Mon Aug 27 05:08:30 2012 +0200
3.3 @@ -0,0 +1,121 @@
3.4 +/*
3.5 +Java 4 Browser Bytecode Translator
3.6 +Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
3.7 +
3.8 +This program is free software: you can redistribute it and/or modify
3.9 +it under the terms of the GNU General Public License as published by
3.10 +the Free Software Foundation, version 2 of the License.
3.11 +
3.12 +This program is distributed in the hope that it will be useful,
3.13 +but WITHOUT ANY WARRANTY; without even the implied warranty of
3.14 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.15 +GNU General Public License for more details.
3.16 +
3.17 +You should have received a copy of the GNU General Public License
3.18 +along with this program. Look for COPYING file in the top folder.
3.19 +If not, see http://opensource.org/licenses/GPL-2.0.
3.20 +*/
3.21 +package org.apidesign.java4browser;
3.22 +
3.23 +import java.io.IOException;
3.24 +import java.io.InputStream;
3.25 +import java.util.List;
3.26 +import org.netbeans.modules.classfile.ByteCodes;
3.27 +import org.netbeans.modules.classfile.ClassFile;
3.28 +import org.netbeans.modules.classfile.Code;
3.29 +import org.netbeans.modules.classfile.Method;
3.30 +import org.netbeans.modules.classfile.Parameter;
3.31 +
3.32 +/** Translator of the code inside class files to JavaScript.
3.33 + *
3.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
3.35 + */
3.36 +public final class ByteCodeToJavaScript {
3.37 + private final ClassFile jc;
3.38 + private final Appendable out;
3.39 +
3.40 + private ByteCodeToJavaScript(ClassFile jc, Appendable out) {
3.41 + this.jc = jc;
3.42 + this.out = out;
3.43 + }
3.44 +
3.45 + /** Converts a given class file to a JavaScript version.
3.46 + * @param fileName the name of the file we are reading
3.47 + * @param classFile input stream with code of the .class file
3.48 + * @param out a {@link StringBuilder} or similar to generate the output to
3.49 + * @throws IOException if something goes wrong during read or write or translating
3.50 + */
3.51 + public static void compile(String fileName, InputStream classFile, Appendable out) throws IOException {
3.52 + ClassFile jc = new ClassFile(classFile, true);
3.53 + ByteCodeToJavaScript compiler = new ByteCodeToJavaScript(jc, out);
3.54 + for (Method m : jc.getMethods()) {
3.55 + if (m.isStatic()) {
3.56 + compiler.generateStaticMethod(m);
3.57 + }
3.58 + }
3.59 + }
3.60 + private void generateStaticMethod(Method m) throws IOException {
3.61 + out.append("function ").append(
3.62 + jc.getName().getExternalName().replace('.', '_')
3.63 + ).append('_').append(
3.64 + m.getName()
3.65 + );
3.66 + out.append(m.getReturnType());
3.67 + List<Parameter> args = m.getParameters();
3.68 + for (Parameter t : args) {
3.69 + out.append(t.getDescriptor());
3.70 + }
3.71 + out.append('(');
3.72 + String space = "";
3.73 + for (int i = 0; i < args.size(); i++) {
3.74 + out.append(space);
3.75 + out.append("arg").append(String.valueOf(i));
3.76 + space = ",";
3.77 + }
3.78 + out.append(") {").append("\n var ");
3.79 + final Code code = m.getCode();
3.80 + int len = code.getMaxLocals();
3.81 + space = "";
3.82 + for (int i = 0; i < len; i++) {
3.83 + out.append(space);
3.84 + out.append("var").append(String.valueOf(i));
3.85 + space = ",";
3.86 + }
3.87 + out.append(";\n var stack = new Array(");
3.88 + out.append(Integer.toString(code.getMaxStack()));
3.89 + out.append(");\n");
3.90 + produceCode(code.getByteCodes());
3.91 + out.append(";\nreturn 1;");
3.92 + out.append("}");
3.93 + }
3.94 +
3.95 + private void produceCode(byte[] byteCodes) throws IOException {
3.96 + for (int i = 0; i < byteCodes.length; i++) {
3.97 + int prev = i;
3.98 + out.append(" ");
3.99 + final int c = (byteCodes[i] + 256) % 256;
3.100 + switch (c) {
3.101 + case ByteCodes.bc_aload_0:
3.102 + case ByteCodes.bc_iload_0:
3.103 + out.append("stack.push(arg0);");
3.104 + break;
3.105 + case ByteCodes.bc_aload_1:
3.106 + case ByteCodes.bc_iload_1:
3.107 + out.append("stack.push(arg1);");
3.108 + break;
3.109 + case ByteCodes.bc_iadd:
3.110 + out.append("stack.push(stack.pop() + stack.pop());");
3.111 + break;
3.112 + case ByteCodes.bc_ireturn:
3.113 + out.append("return stack.pop();");
3.114 + }
3.115 + out.append("/*");
3.116 + for (int j = prev; j <= i; j++) {
3.117 + out.append(" ");
3.118 + final int cc = (byteCodes[j] + 256) % 256;
3.119 + out.append(Integer.toString(cc));
3.120 + }
3.121 + out.append("*/\n");
3.122 + }
3.123 + }
3.124 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/src/test/java/org/apidesign/java4browser/StaticMethod.java Mon Aug 27 05:08:30 2012 +0200
4.3 @@ -0,0 +1,28 @@
4.4 +/*
4.5 +Java 4 Browser Bytecode Translator
4.6 +Copyright (C) 2012-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.java4browser;
4.22 +
4.23 +/**
4.24 + *
4.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
4.26 + */
4.27 +public class StaticMethod {
4.28 + public static int sum(int x, int y) {
4.29 + return x + y;
4.30 + }
4.31 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/src/test/java/org/apidesign/java4browser/StaticMethodTest.java Mon Aug 27 05:08:30 2012 +0200
5.3 @@ -0,0 +1,57 @@
5.4 +/*
5.5 +Java 4 Browser Bytecode Translator
5.6 +Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.7 +
5.8 +This program is free software: you can redistribute it and/or modify
5.9 +it under the terms of the GNU General Public License as published by
5.10 +the Free Software Foundation, version 2 of the License.
5.11 +
5.12 +This program is distributed in the hope that it will be useful,
5.13 +but WITHOUT ANY WARRANTY; without even the implied warranty of
5.14 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.15 +GNU General Public License for more details.
5.16 +
5.17 +You should have received a copy of the GNU General Public License
5.18 +along with this program. Look for COPYING file in the top folder.
5.19 +If not, see http://opensource.org/licenses/GPL-2.0.
5.20 +*/
5.21 +package org.apidesign.java4browser;
5.22 +
5.23 +import java.io.IOException;
5.24 +import java.io.InputStream;
5.25 +import javax.script.Invocable;
5.26 +import javax.script.ScriptEngine;
5.27 +import javax.script.ScriptEngineManager;
5.28 +import javax.script.ScriptException;
5.29 +import static org.testng.Assert.*;
5.30 +import org.testng.annotations.Test;
5.31 +
5.32 +/** Checks the basic behavior of the translator.
5.33 + *
5.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
5.35 + */
5.36 +public class StaticMethodTest {
5.37 + @Test public void threePlusFour() throws Exception {
5.38 + Invocable i = compileClass("StaticMethod.class");
5.39 +
5.40 + Object ret = i.invokeFunction("org_apidesign_java4browser_StaticMethod_sumIII", 3, 4);
5.41 + assertEquals(ret, Double.valueOf(7), "Should be seven");
5.42 + }
5.43 +
5.44 + static Invocable compileClass(String name) throws ScriptException, IOException {
5.45 + InputStream is = StaticMethodTest.class.getResourceAsStream(name);
5.46 + assertNotNull(is, "Class file found");
5.47 + StringBuilder sb = new StringBuilder();
5.48 + ByteCodeToJavaScript.compile(name, is, sb);
5.49 + ScriptEngineManager sem = new ScriptEngineManager();
5.50 + ScriptEngine js = sem.getEngineByExtension("js");
5.51 + try {
5.52 + Object res = js.eval(sb.toString());
5.53 + assertTrue(js instanceof Invocable, "It is invocable object: " + res);
5.54 + return (Invocable)js;
5.55 + } catch (ScriptException ex) {
5.56 + fail("Could not compile:\n" + sb, ex);
5.57 + return null;
5.58 + }
5.59 + }
5.60 +}