Getting ready for multiple projects inside one Hg repository
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 24 Sep 2012 11:07:38 +0200
changeset 22b9318fe303cd
parent 21 d8807b6a636a
child 23 5d076ad40851
Getting ready for multiple projects inside one Hg repository
nb-configuration.xml
pom.xml
src/header.txt
src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java
src/test/java/org/apidesign/java4browser/Array.java
src/test/java/org/apidesign/java4browser/ArrayTest.java
src/test/java/org/apidesign/java4browser/GetByte.java
src/test/java/org/apidesign/java4browser/Instance.java
src/test/java/org/apidesign/java4browser/InstanceSub.java
src/test/java/org/apidesign/java4browser/InstanceTest.java
src/test/java/org/apidesign/java4browser/StaticMethod.java
src/test/java/org/apidesign/java4browser/StaticMethodTest.java
vm/nb-configuration.xml
vm/pom.xml
vm/src/header.txt
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
vm/src/test/java/org/apidesign/vm4brwsr/Array.java
vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java
vm/src/test/java/org/apidesign/vm4brwsr/GetByte.java
vm/src/test/java/org/apidesign/vm4brwsr/Instance.java
vm/src/test/java/org/apidesign/vm4brwsr/InstanceSub.java
vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java
vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java
vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java
     1.1 --- a/nb-configuration.xml	Mon Sep 24 09:35:00 2012 +0200
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,18 +0,0 @@
     1.4 -<?xml version="1.0" encoding="UTF-8"?>
     1.5 -<project-shared-configuration>
     1.6 -    <!--
     1.7 -This file contains additional configuration written by modules in the NetBeans IDE.
     1.8 -The configuration is intended to be shared among all the users of project and
     1.9 -therefore it is assumed to be part of version control checkout.
    1.10 -Without this configuration present, some functionality in the IDE may be limited or fail altogether.
    1.11 --->
    1.12 -    <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
    1.13 -        <!--
    1.14 -Properties that influence various parts of the IDE, especially code formatting and the like. 
    1.15 -You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
    1.16 -That way multiple projects can share the same settings (useful for formatting rules for example).
    1.17 -Any value defined here will override the pom.xml file value but is only applicable to the current project.
    1.18 --->
    1.19 -        <netbeans.compile.on.save>all</netbeans.compile.on.save>
    1.20 -    </properties>
    1.21 -</project-shared-configuration>
     2.1 --- a/pom.xml	Mon Sep 24 09:35:00 2012 +0200
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,86 +0,0 @@
     2.4 -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     2.5 -  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     2.6 -  <modelVersion>4.0.0</modelVersion>
     2.7 -
     2.8 -  <groupId>org.apidesign</groupId>
     2.9 -  <artifactId>java4browser</artifactId>
    2.10 -  <version>0.1-SNAPSHOT</version>
    2.11 -  <packaging>jar</packaging>
    2.12 -
    2.13 -  <name>java4browser</name>
    2.14 -  <url>http://java4browser.apidesign.org</url>
    2.15 -
    2.16 -  <properties>
    2.17 -    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    2.18 -    <author.name>Jaroslav Tulach</author.name>
    2.19 -    <author.email>jaroslav.tulach@apidesign.org</author.email>
    2.20 -  </properties>
    2.21 -  
    2.22 -  <repositories>
    2.23 -      <repository>
    2.24 -          <id>netbeans</id>
    2.25 -          <name>NetBeans</name>
    2.26 -          <url>http://bits.netbeans.org/maven2/</url>
    2.27 -      </repository>
    2.28 -  </repositories>
    2.29 -  <pluginRepositories>
    2.30 -    <pluginRepository>
    2.31 -        <id>mc-release</id>
    2.32 -        <name>Local Maven repository of releases</name>
    2.33 -        <url>http://mc-repo.googlecode.com/svn/maven2/releases</url>
    2.34 -        <snapshots>
    2.35 -            <enabled>false</enabled>
    2.36 -        </snapshots>
    2.37 -        <releases>
    2.38 -            <enabled>true</enabled>
    2.39 -        </releases>
    2.40 -    </pluginRepository>
    2.41 -  </pluginRepositories>
    2.42 -  <scm>
    2.43 -      <connection>scm:hg:http://source.apidesign.org/hg/quoridor</connection>
    2.44 -      <url>http://source.apidesign.org/hg/quoridor</url>
    2.45 -  </scm>
    2.46 -  <licenses>
    2.47 -    <license>
    2.48 -        <name>GPL-2.0</name>
    2.49 -        <url>http://opensource.org/licenses/GPL-2.0</url>
    2.50 -        <distribution>repo</distribution>
    2.51 -    </license>
    2.52 -  </licenses>
    2.53 -  <organization>
    2.54 -      <name>API Design</name>
    2.55 -      <url>http://apidesign.org</url>
    2.56 -  </organization>
    2.57 -    <build>
    2.58 -        <plugins>
    2.59 -            <plugin>
    2.60 -                <groupId>com.mycila.maven-license-plugin</groupId>
    2.61 -                <artifactId>maven-license-plugin</artifactId>
    2.62 -                <version>1.9.0</version>
    2.63 -                <configuration>
    2.64 -                    <header>src/header.txt</header>
    2.65 -                </configuration>
    2.66 -            </plugin>
    2.67 -        </plugins>
    2.68 -    </build>
    2.69 -  <dependencies>
    2.70 -    <dependency>
    2.71 -      <groupId>org.testng</groupId>
    2.72 -      <artifactId>testng</artifactId>
    2.73 -      <version>6.7</version>
    2.74 -      <scope>test</scope>
    2.75 -      <exclusions>
    2.76 -        <exclusion>
    2.77 -          <artifactId>junit</artifactId>
    2.78 -          <groupId>junit</groupId>
    2.79 -        </exclusion>
    2.80 -      </exclusions>
    2.81 -    </dependency>
    2.82 -    <dependency>
    2.83 -      <groupId>org.netbeans.api</groupId>
    2.84 -      <artifactId>org-netbeans-modules-classfile</artifactId>
    2.85 -      <version>RELEASE72</version>
    2.86 -      <type>jar</type>
    2.87 -    </dependency>
    2.88 -  </dependencies>
    2.89 -</project>
     3.1 --- a/src/header.txt	Mon Sep 24 09:35:00 2012 +0200
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,15 +0,0 @@
     3.4 -Java 4 Browser Bytecode Translator
     3.5 -Copyright (C) 2012-${year} Jaroslav Tulach <jaroslav.tulach@apidesign.org>
     3.6 -
     3.7 -This program is free software: you can redistribute it and/or modify
     3.8 -it under the terms of the GNU General Public License as published by
     3.9 -the Free Software Foundation, version 2 of the License.
    3.10 -
    3.11 -This program is distributed in the hope that it will be useful,
    3.12 -but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.13 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.14 -GNU General Public License for more details.
    3.15 -
    3.16 -You should have received a copy of the GNU General Public License
    3.17 -along with this program. Look for COPYING file in the top folder.
    3.18 -If not, see http://opensource.org/licenses/GPL-2.0.
     4.1 --- a/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java	Mon Sep 24 09:35:00 2012 +0200
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,793 +0,0 @@
     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 -import java.io.IOException;
    4.24 -import java.io.InputStream;
    4.25 -import java.util.ArrayList;
    4.26 -import java.util.Collection;
    4.27 -import java.util.List;
    4.28 -import static org.netbeans.modules.classfile.ByteCodes.*;
    4.29 -import org.netbeans.modules.classfile.CPClassInfo;
    4.30 -import org.netbeans.modules.classfile.CPEntry;
    4.31 -import org.netbeans.modules.classfile.CPFieldInfo;
    4.32 -import org.netbeans.modules.classfile.CPMethodInfo;
    4.33 -import org.netbeans.modules.classfile.CPStringInfo;
    4.34 -import org.netbeans.modules.classfile.ClassFile;
    4.35 -import org.netbeans.modules.classfile.ClassName;
    4.36 -import org.netbeans.modules.classfile.Code;
    4.37 -import org.netbeans.modules.classfile.Method;
    4.38 -import org.netbeans.modules.classfile.Parameter;
    4.39 -import org.netbeans.modules.classfile.Variable;
    4.40 -
    4.41 -/** Translator of the code inside class files to JavaScript.
    4.42 - *
    4.43 - * @author Jaroslav Tulach <jtulach@netbeans.org>
    4.44 - */
    4.45 -public final class ByteCodeToJavaScript {
    4.46 -    private final ClassFile jc;
    4.47 -    private final Appendable out;
    4.48 -    private final Collection<? super String> references;
    4.49 -
    4.50 -    private ByteCodeToJavaScript(
    4.51 -        ClassFile jc, Appendable out, Collection<? super String> references
    4.52 -    ) {
    4.53 -        this.jc = jc;
    4.54 -        this.out = out;
    4.55 -        this.references = references;
    4.56 -    }
    4.57 -
    4.58 -    /**
    4.59 -     * Converts a given class file to a JavaScript version.
    4.60 -     *
    4.61 -     * @param classFile input stream with code of the .class file
    4.62 -     * @param out a {@link StringBuilder} or similar to generate the output to
    4.63 -     * @param references a write only collection where the system adds list of
    4.64 -     *   other classes that were referenced and should be loaded in order the
    4.65 -     *   generated JavaScript code works properly. The names are in internal 
    4.66 -     *   JVM form so String is <code>java/lang/String</code>. Can be <code>null</code>
    4.67 -     *   if one is not interested in knowing references
    4.68 -     * @throws IOException if something goes wrong during read or write or translating
    4.69 -     */
    4.70 -    
    4.71 -    public static void compile(
    4.72 -        InputStream classFile, Appendable out,
    4.73 -        Collection<? super String> references
    4.74 -    ) throws IOException {
    4.75 -        ClassFile jc = new ClassFile(classFile, true);
    4.76 -        ByteCodeToJavaScript compiler = new ByteCodeToJavaScript(
    4.77 -            jc, out, references
    4.78 -        );
    4.79 -        List<String> toInitilize = new ArrayList<String>();
    4.80 -        for (Method m : jc.getMethods()) {
    4.81 -            if (m.isStatic()) {
    4.82 -                compiler.generateStaticMethod(m, toInitilize);
    4.83 -            } else {
    4.84 -                compiler.generateInstanceMethod(m);
    4.85 -            }
    4.86 -        }
    4.87 -        for (Variable v : jc.getVariables()) {
    4.88 -            if (v.isStatic()) {
    4.89 -                compiler.generateStaticField(v);
    4.90 -            }
    4.91 -        }
    4.92 -        
    4.93 -        final String className = jc.getName().getInternalName().replace('/', '_');
    4.94 -        out.append("\nfunction ").append(className);
    4.95 -        out.append("() {");
    4.96 -        for (Method m : jc.getMethods()) {
    4.97 -            if (!m.isStatic()) {
    4.98 -                compiler.generateMethodReference(m);
    4.99 -            }
   4.100 -        }
   4.101 -        for (Variable v : jc.getVariables()) {
   4.102 -            if (!v.isStatic()) {
   4.103 -                out.append("\n  this." + v.getName() + " = 0;");
   4.104 -            }
   4.105 -        }
   4.106 -        out.append("\n  this.$instOf_").append(className).append(" = true;");
   4.107 -        out.append("\n}");
   4.108 -        ClassName sc = jc.getSuperClass();
   4.109 -        if (sc != null) {
   4.110 -            out.append("\n").append(className)
   4.111 -               .append(".prototype = new ").append(sc.getInternalName().replace('/', '_'));
   4.112 -        }
   4.113 -        for (String init : toInitilize) {
   4.114 -            out.append("\n").append(init).append("();");
   4.115 -        }
   4.116 -    }
   4.117 -    private void generateStaticMethod(Method m, List<String> toInitilize) throws IOException {
   4.118 -        final String mn = findMethodName(m);
   4.119 -        out.append("\nfunction ").append(
   4.120 -            jc.getName().getInternalName().replace('/', '_')
   4.121 -        ).append('_').append(mn);
   4.122 -        if (mn.equals("classV")) {
   4.123 -            toInitilize.add(jc.getName().getInternalName().replace('/', '_') + '_' + mn);
   4.124 -        }
   4.125 -        out.append('(');
   4.126 -        String space = "";
   4.127 -        List<Parameter> args = m.getParameters();
   4.128 -        for (int index = 0, i = 0; i < args.size(); i++) {
   4.129 -            out.append(space);
   4.130 -            out.append("arg").append(String.valueOf(index));
   4.131 -            space = ",";
   4.132 -            final String desc = args.get(i).getDescriptor();
   4.133 -            if ("D".equals(desc) || "J".equals(desc)) {
   4.134 -                index += 2;
   4.135 -            } else {
   4.136 -                index++;
   4.137 -            }
   4.138 -        }
   4.139 -        out.append(") {").append("\n");
   4.140 -        final Code code = m.getCode();
   4.141 -        if (code != null) {
   4.142 -            int len = code.getMaxLocals();
   4.143 -            for (int index = args.size(), i = args.size(); i < len; i++) {
   4.144 -                out.append("  var ");
   4.145 -                out.append("arg").append(String.valueOf(i)).append(";\n");
   4.146 -            }
   4.147 -            out.append("  var stack = new Array();\n");
   4.148 -            produceCode(code.getByteCodes());
   4.149 -        } else {
   4.150 -            out.append("  /* no code found for ").append(m.getTypeSignature()).append(" */\n");
   4.151 -        }
   4.152 -        out.append("}");
   4.153 -    }
   4.154 -    
   4.155 -    private void generateMethodReference(Method m) throws IOException {
   4.156 -        final String name = findMethodName(m);
   4.157 -        out.append("\n  this.").append(name).append(" = ")
   4.158 -           .append(jc.getName().getInternalName().replace('/', '_'))
   4.159 -           .append('_').append(name).append(";");
   4.160 -    }
   4.161 -    
   4.162 -    private void generateInstanceMethod(Method m) throws IOException {
   4.163 -        out.append("\nfunction ").append(
   4.164 -            jc.getName().getInternalName().replace('/', '_')
   4.165 -        ).append('_').append(findMethodName(m));
   4.166 -        out.append("(arg0");
   4.167 -        String space = ",";
   4.168 -        List<Parameter> args = m.getParameters();
   4.169 -        for (int index = 1, i = 0; i < args.size(); i++) {
   4.170 -            out.append(space);
   4.171 -            out.append("arg").append(String.valueOf(index));
   4.172 -            final String desc = args.get(i).getDescriptor();
   4.173 -            if ("D".equals(desc) || "J".equals(desc)) {
   4.174 -                index += 2;
   4.175 -            } else {
   4.176 -                index++;
   4.177 -            }
   4.178 -        }
   4.179 -        out.append(") {").append("\n");
   4.180 -        final Code code = m.getCode();
   4.181 -        if (code != null) {
   4.182 -            int len = code.getMaxLocals();
   4.183 -            for (int index = args.size(), i = args.size(); i < len; i++) {
   4.184 -                out.append("  var ");
   4.185 -                out.append("arg").append(String.valueOf(i + 1)).append(";\n");
   4.186 -            }
   4.187 -            out.append(";\n  var stack = new Array(");
   4.188 -            out.append(Integer.toString(code.getMaxStack()));
   4.189 -            out.append(");\n");
   4.190 -            produceCode(code.getByteCodes());
   4.191 -        } else {
   4.192 -            out.append("  /* no code found for ").append(m.getTypeSignature()).append(" */\n");
   4.193 -        }
   4.194 -        out.append("}");
   4.195 -    }
   4.196 -
   4.197 -    private void produceCode(byte[] byteCodes) throws IOException {
   4.198 -        out.append("\n  var gt = 0;\n  for(;;) switch(gt) {\n");
   4.199 -        for (int i = 0; i < byteCodes.length; i++) {
   4.200 -            int prev = i;
   4.201 -            out.append("    case " + i).append(": ");
   4.202 -            final int c = (byteCodes[i] + 256) % 256;
   4.203 -            switch (c) {
   4.204 -                case bc_aload_0:
   4.205 -                case bc_iload_0:
   4.206 -                case bc_lload_0:
   4.207 -                case bc_fload_0:
   4.208 -                case bc_dload_0:
   4.209 -                    out.append("stack.push(arg0);");
   4.210 -                    break;
   4.211 -                case bc_aload_1:
   4.212 -                case bc_iload_1:
   4.213 -                case bc_lload_1:
   4.214 -                case bc_fload_1:
   4.215 -                case bc_dload_1:
   4.216 -                    out.append("stack.push(arg1);");
   4.217 -                    break;
   4.218 -                case bc_aload_2:
   4.219 -                case bc_iload_2:
   4.220 -                case bc_lload_2:
   4.221 -                case bc_fload_2:
   4.222 -                case bc_dload_2:
   4.223 -                    out.append("stack.push(arg2);");
   4.224 -                    break;
   4.225 -                case bc_aload_3:
   4.226 -                case bc_iload_3:
   4.227 -                case bc_lload_3:
   4.228 -                case bc_fload_3:
   4.229 -                case bc_dload_3:
   4.230 -                    out.append("stack.push(arg3);");
   4.231 -                    break;
   4.232 -                case bc_iload:
   4.233 -                case bc_lload:
   4.234 -                case bc_fload:
   4.235 -                case bc_dload:
   4.236 -                case bc_aload: {
   4.237 -                    final int indx = (byteCodes[++i] + 256) % 256;
   4.238 -                    out.append("stack.push(arg").append(indx + ");");
   4.239 -                    break;
   4.240 -                }
   4.241 -                case bc_astore_0:
   4.242 -                case bc_istore_0:
   4.243 -                case bc_lstore_0:
   4.244 -                case bc_fstore_0:
   4.245 -                case bc_dstore_0:
   4.246 -                    out.append("arg0 = stack.pop();");
   4.247 -                    break;
   4.248 -                case bc_astore_1:
   4.249 -                case bc_istore_1:
   4.250 -                case bc_lstore_1:
   4.251 -                case bc_fstore_1:
   4.252 -                case bc_dstore_1:
   4.253 -                    out.append("arg1 = stack.pop();");
   4.254 -                    break;
   4.255 -                case bc_astore_2:
   4.256 -                case bc_istore_2:
   4.257 -                case bc_lstore_2:
   4.258 -                case bc_fstore_2:
   4.259 -                case bc_dstore_2:
   4.260 -                    out.append("arg2 = stack.pop();");
   4.261 -                    break;
   4.262 -                case bc_astore_3:
   4.263 -                case bc_istore_3:
   4.264 -                case bc_lstore_3:
   4.265 -                case bc_fstore_3:
   4.266 -                case bc_dstore_3:
   4.267 -                    out.append("arg3 = stack.pop();");
   4.268 -                    break;
   4.269 -                case bc_iadd:
   4.270 -                case bc_ladd:
   4.271 -                case bc_fadd:
   4.272 -                case bc_dadd:
   4.273 -                    out.append("stack.push(stack.pop() + stack.pop());");
   4.274 -                    break;
   4.275 -                case bc_isub:
   4.276 -                case bc_lsub:
   4.277 -                case bc_fsub:
   4.278 -                case bc_dsub:
   4.279 -                    out.append("{ var tmp = stack.pop(); stack.push(stack.pop() - tmp); }");
   4.280 -                    break;
   4.281 -                case bc_imul:
   4.282 -                case bc_lmul:
   4.283 -                case bc_fmul:
   4.284 -                case bc_dmul:
   4.285 -                    out.append("stack.push(stack.pop() * stack.pop());");
   4.286 -                    break;
   4.287 -                case bc_idiv:
   4.288 -                case bc_ldiv:
   4.289 -                    out.append("{ var tmp = stack.pop(); stack.push(Math.floor(stack.pop() / tmp)); }");
   4.290 -                    break;
   4.291 -                case bc_fdiv:
   4.292 -                case bc_ddiv:
   4.293 -                    out.append("{ var tmp = stack.pop(); stack.push(stack.pop() / tmp); }");
   4.294 -                    break;
   4.295 -                case bc_iand:
   4.296 -                case bc_land:
   4.297 -                    out.append("stack.push(stack.pop() & stack.pop());");
   4.298 -                    break;
   4.299 -                case bc_ior:
   4.300 -                case bc_lor:
   4.301 -                    out.append("stack.push(stack.pop() | stack.pop());");
   4.302 -                    break;
   4.303 -                case bc_ixor:
   4.304 -                case bc_lxor:
   4.305 -                    out.append("stack.push(stack.pop() ^ stack.pop());");
   4.306 -                    break;
   4.307 -                case bc_iinc: {
   4.308 -                    final int varIndx = (byteCodes[++i] + 256) % 256;
   4.309 -                    final int incrBy = (byteCodes[++i] + 256) % 256;
   4.310 -                    if (incrBy == 1) {
   4.311 -                        out.append("arg" + varIndx).append("++;");
   4.312 -                    } else {
   4.313 -                        out.append("arg" + varIndx).append(" += " + incrBy).append(";");
   4.314 -                    }
   4.315 -                    break;
   4.316 -                }
   4.317 -                case bc_return:
   4.318 -                    out.append("return;");
   4.319 -                    break;
   4.320 -                case bc_ireturn:
   4.321 -                case bc_lreturn:
   4.322 -                case bc_freturn:
   4.323 -                case bc_dreturn:
   4.324 -                case bc_areturn:
   4.325 -                    out.append("return stack.pop();");
   4.326 -                    break;
   4.327 -                case bc_i2l:
   4.328 -                case bc_i2f:
   4.329 -                case bc_i2d:
   4.330 -                case bc_l2i:
   4.331 -                    // max int check?
   4.332 -                case bc_l2f:
   4.333 -                case bc_l2d:
   4.334 -                case bc_f2d:
   4.335 -                case bc_d2f:
   4.336 -                    out.append("/* number conversion */");
   4.337 -                    break;
   4.338 -                case bc_f2i:
   4.339 -                case bc_f2l:
   4.340 -                case bc_d2i:
   4.341 -                case bc_d2l:
   4.342 -                    out.append("stack.push(Math.floor(stack.pop()));");
   4.343 -                    break;
   4.344 -                case bc_i2b:
   4.345 -                case bc_i2c:
   4.346 -                case bc_i2s:
   4.347 -                    out.append("/* number conversion */");
   4.348 -                    break;
   4.349 -                case bc_iconst_0:
   4.350 -                case bc_dconst_0:
   4.351 -                case bc_lconst_0:
   4.352 -                case bc_fconst_0:
   4.353 -                    out.append("stack.push(0);");
   4.354 -                    break;
   4.355 -                case bc_iconst_1:
   4.356 -                case bc_lconst_1:
   4.357 -                case bc_fconst_1:
   4.358 -                case bc_dconst_1:
   4.359 -                    out.append("stack.push(1);");
   4.360 -                    break;
   4.361 -                case bc_iconst_2:
   4.362 -                case bc_fconst_2:
   4.363 -                    out.append("stack.push(2);");
   4.364 -                    break;
   4.365 -                case bc_iconst_3:
   4.366 -                    out.append("stack.push(3);");
   4.367 -                    break;
   4.368 -                case bc_iconst_4:
   4.369 -                    out.append("stack.push(4);");
   4.370 -                    break;
   4.371 -                case bc_iconst_5:
   4.372 -                    out.append("stack.push(5);");
   4.373 -                    break;
   4.374 -                case bc_ldc: {
   4.375 -                    int indx = byteCodes[++i];
   4.376 -                    CPEntry entry = jc.getConstantPool().get(indx);
   4.377 -                    String v = encodeConstant(entry);
   4.378 -                    out.append("stack.push(").append(v).append(");");
   4.379 -                    break;
   4.380 -                }
   4.381 -                case bc_ldc_w:
   4.382 -                case bc_ldc2_w: {
   4.383 -                    int indx = readIntArg(byteCodes, i);
   4.384 -                    CPEntry entry = jc.getConstantPool().get(indx);
   4.385 -                    i += 2;
   4.386 -                    String v = encodeConstant(entry);
   4.387 -                    out.append("stack.push(").append(v).append(");");
   4.388 -                    break;
   4.389 -                }
   4.390 -                case bc_lcmp:
   4.391 -                case bc_fcmpl:
   4.392 -                case bc_fcmpg:
   4.393 -                case bc_dcmpl:
   4.394 -                case bc_dcmpg: {
   4.395 -                    out.append("{ var delta = stack.pop() - stack.pop(); stack.push(delta < 0 ?-1 : (delta == 0 ? 0 : 1)); }");
   4.396 -                    break;
   4.397 -                }
   4.398 -                case bc_if_icmpeq: {
   4.399 -                    i = generateIf(byteCodes, i, "==");
   4.400 -                    break;
   4.401 -                }
   4.402 -                case bc_ifeq: {
   4.403 -                    int indx = i + readIntArg(byteCodes, i);
   4.404 -                    out.append("if (stack.pop() == 0) { gt = " + indx);
   4.405 -                    out.append("; continue; }");
   4.406 -                    i += 2;
   4.407 -                    break;
   4.408 -                }
   4.409 -                case bc_ifne: {
   4.410 -                    int indx = i + readIntArg(byteCodes, i);
   4.411 -                    out.append("if (stack.pop() != 0) { gt = " + indx);
   4.412 -                    out.append("; continue; }");
   4.413 -                    i += 2;
   4.414 -                    break;
   4.415 -                }
   4.416 -                case bc_iflt: {
   4.417 -                    int indx = i + readIntArg(byteCodes, i);
   4.418 -                    out.append("if (stack.pop() < 0) { gt = " + indx);
   4.419 -                    out.append("; continue; }");
   4.420 -                    i += 2;
   4.421 -                    break;
   4.422 -                }
   4.423 -                case bc_ifle: {
   4.424 -                    int indx = i + readIntArg(byteCodes, i);
   4.425 -                    out.append("if (stack.pop() <= 0) { gt = " + indx);
   4.426 -                    out.append("; continue; }");
   4.427 -                    i += 2;
   4.428 -                    break;
   4.429 -                }
   4.430 -                case bc_ifgt: {
   4.431 -                    int indx = i + readIntArg(byteCodes, i);
   4.432 -                    out.append("if (stack.pop() > 0) { gt = " + indx);
   4.433 -                    out.append("; continue; }");
   4.434 -                    i += 2;
   4.435 -                    break;
   4.436 -                }
   4.437 -                case bc_ifge: {
   4.438 -                    int indx = i + readIntArg(byteCodes, i);
   4.439 -                    out.append("if (stack.pop() >= 0) { gt = " + indx);
   4.440 -                    out.append("; continue; }");
   4.441 -                    i += 2;
   4.442 -                    break;
   4.443 -                }
   4.444 -                case bc_ifnonnull: {
   4.445 -                    int indx = i + readIntArg(byteCodes, i);
   4.446 -                    out.append("if (stack.pop()) { gt = " + indx);
   4.447 -                    out.append("; continue; }");
   4.448 -                    i += 2;
   4.449 -                    break;
   4.450 -                }
   4.451 -                case bc_ifnull: {
   4.452 -                    int indx = i + readIntArg(byteCodes, i);
   4.453 -                    out.append("if (!stack.pop()) { gt = " + indx);
   4.454 -                    out.append("; continue; }");
   4.455 -                    i += 2;
   4.456 -                    break;
   4.457 -                }
   4.458 -                case bc_if_icmpne:
   4.459 -                    i = generateIf(byteCodes, i, "!=");
   4.460 -                    break;
   4.461 -                case bc_if_icmplt:
   4.462 -                    i = generateIf(byteCodes, i, ">");
   4.463 -                    break;
   4.464 -                case bc_if_icmple:
   4.465 -                    i = generateIf(byteCodes, i, ">=");
   4.466 -                    break;
   4.467 -                case bc_if_icmpgt:
   4.468 -                    i = generateIf(byteCodes, i, "<");
   4.469 -                    break;
   4.470 -                case bc_if_icmpge:
   4.471 -                    i = generateIf(byteCodes, i, "<=");
   4.472 -                    break;
   4.473 -                case bc_goto: {
   4.474 -                    int indx = i + readIntArg(byteCodes, i);
   4.475 -                    out.append("gt = " + indx).append("; continue;");
   4.476 -                    i += 2;
   4.477 -                    break;
   4.478 -                }
   4.479 -                case bc_invokeinterface:
   4.480 -                case bc_invokevirtual:
   4.481 -                    i = invokeVirtualMethod(byteCodes, i);
   4.482 -                    break;
   4.483 -                case bc_invokespecial:
   4.484 -                    i = invokeStaticMethod(byteCodes, i, false);
   4.485 -                    break;
   4.486 -                case bc_invokestatic:
   4.487 -                    i = invokeStaticMethod(byteCodes, i, true);
   4.488 -                    break;
   4.489 -                case bc_new: {
   4.490 -                    int indx = readIntArg(byteCodes, i);
   4.491 -                    CPClassInfo ci = jc.getConstantPool().getClass(indx);
   4.492 -                    out.append("stack.push(");
   4.493 -                    out.append("new ").append(ci.getClassName().getInternalName().replace('/','_'));
   4.494 -                    out.append(");");
   4.495 -                    addReference(ci.getClassName().getInternalName());
   4.496 -                    i += 2;
   4.497 -                    break;
   4.498 -                }
   4.499 -                case bc_newarray: {
   4.500 -                    int type = byteCodes[i++];
   4.501 -                    out.append("stack.push(new Array(stack.pop()));");
   4.502 -                    break;
   4.503 -                }
   4.504 -                case bc_anewarray: {
   4.505 -                    i += 2; // skip type of array
   4.506 -                    out.append("stack.push(new Array(stack.pop()));");
   4.507 -                    break;
   4.508 -                }
   4.509 -                case bc_arraylength:
   4.510 -                    out.append("stack.push(stack.pop().length);");
   4.511 -                    break;
   4.512 -                case bc_iastore:
   4.513 -                case bc_lastore:
   4.514 -                case bc_fastore:
   4.515 -                case bc_dastore:
   4.516 -                case bc_aastore:
   4.517 -                case bc_bastore:
   4.518 -                case bc_castore:
   4.519 -                case bc_sastore: {
   4.520 -                    out.append("{ var value = stack.pop(); var indx = stack.pop(); stack.pop()[indx] = value; }");
   4.521 -                    break;
   4.522 -                }
   4.523 -                case bc_iaload:
   4.524 -                case bc_laload:
   4.525 -                case bc_faload:
   4.526 -                case bc_daload:
   4.527 -                case bc_aaload:
   4.528 -                case bc_baload:
   4.529 -                case bc_caload:
   4.530 -                case bc_saload: {
   4.531 -                    out.append("{ var indx = stack.pop(); stack.push(stack.pop()[indx]); }");
   4.532 -                    break;
   4.533 -                }
   4.534 -                case bc_dup:
   4.535 -                    out.append("stack.push(stack[stack.length - 1]);");
   4.536 -                    break;
   4.537 -                case bc_bipush:
   4.538 -                    out.append("stack.push(" + byteCodes[++i] + ");");
   4.539 -                    break;
   4.540 -                case bc_getfield: {
   4.541 -                    int indx = readIntArg(byteCodes, i);
   4.542 -                    CPFieldInfo fi = (CPFieldInfo) jc.getConstantPool().get(indx);
   4.543 -                    out.append("stack.push(stack.pop().").append(fi.getFieldName()).append(");");
   4.544 -                    i += 2;
   4.545 -                    break;
   4.546 -                }
   4.547 -                case bc_getstatic: {
   4.548 -                    int indx = readIntArg(byteCodes, i);
   4.549 -                    CPFieldInfo fi = (CPFieldInfo) jc.getConstantPool().get(indx);
   4.550 -                    final String in = fi.getClassName().getInternalName();
   4.551 -                    out.append("stack.push(").append(in.replace('/', '_'));
   4.552 -                    out.append('_').append(fi.getFieldName()).append(");");
   4.553 -                    i += 2;
   4.554 -                    addReference(in);
   4.555 -                    break;
   4.556 -                }
   4.557 -                case bc_putstatic: {
   4.558 -                    int indx = readIntArg(byteCodes, i);
   4.559 -                    CPFieldInfo fi = (CPFieldInfo) jc.getConstantPool().get(indx);
   4.560 -                    final String in = fi.getClassName().getInternalName();
   4.561 -                    out.append(in.replace('/', '_'));
   4.562 -                    out.append('_').append(fi.getFieldName()).append(" = stack.pop();");
   4.563 -                    i += 2;
   4.564 -                    addReference(in);
   4.565 -                    break;
   4.566 -                }
   4.567 -                case bc_putfield: {
   4.568 -                    int indx = readIntArg(byteCodes, i);
   4.569 -                    CPFieldInfo fi = (CPFieldInfo) jc.getConstantPool().get(indx);
   4.570 -                    out.append("{ var v = stack.pop(); stack.pop().")
   4.571 -                       .append(fi.getFieldName()).append(" = v; }");
   4.572 -                    i += 2;
   4.573 -                    break;
   4.574 -                }
   4.575 -                case bc_instanceof: {
   4.576 -                    int indx = readIntArg(byteCodes, i);
   4.577 -                    CPClassInfo ci = jc.getConstantPool().getClass(indx);
   4.578 -                    out.append("stack.push(stack.pop().$instOf_")
   4.579 -                       .append(ci.getClassName().getInternalName().replace('/', '_'))
   4.580 -                       .append(" ? 1 : 0);");
   4.581 -                    i += 2;
   4.582 -                }
   4.583 -                    
   4.584 -            }
   4.585 -            out.append(" /*");
   4.586 -            for (int j = prev; j <= i; j++) {
   4.587 -                out.append(" ");
   4.588 -                final int cc = (byteCodes[j] + 256) % 256;
   4.589 -                out.append(Integer.toString(cc));
   4.590 -            }
   4.591 -            out.append("*/\n");
   4.592 -        }
   4.593 -        out.append("  }\n");
   4.594 -    }
   4.595 -
   4.596 -    private int generateIf(byte[] byteCodes, int i, final String test) throws IOException {
   4.597 -        int indx = i + readIntArg(byteCodes, i);
   4.598 -        out.append("if (stack.pop() ").append(test).append(" stack.pop()) { gt = " + indx);
   4.599 -        out.append("; continue; }");
   4.600 -        return i + 2;
   4.601 -    }
   4.602 -
   4.603 -    private int readIntArg(byte[] byteCodes, int offsetInstruction) {
   4.604 -        final int indxHi = byteCodes[offsetInstruction + 1] << 8;
   4.605 -        final int indxLo = byteCodes[offsetInstruction + 2];
   4.606 -        return (indxHi & 0xffffff00) | (indxLo & 0xff);
   4.607 -    }
   4.608 -    
   4.609 -    private static int countArgs(String descriptor, boolean[] hasReturnType, StringBuilder sig) {
   4.610 -        int cnt = 0;
   4.611 -        int i = 0;
   4.612 -        Boolean count = null;
   4.613 -        int firstPos = sig.length();
   4.614 -        while (i < descriptor.length()) {
   4.615 -            char ch = descriptor.charAt(i++);
   4.616 -            switch (ch) {
   4.617 -                case '(':
   4.618 -                    count = true;
   4.619 -                    continue;
   4.620 -                case ')':
   4.621 -                    count = false;
   4.622 -                    continue;
   4.623 -                case 'B': 
   4.624 -                case 'C': 
   4.625 -                case 'D': 
   4.626 -                case 'F': 
   4.627 -                case 'I': 
   4.628 -                case 'J': 
   4.629 -                case 'S': 
   4.630 -                case 'Z': 
   4.631 -                    if (count) {
   4.632 -                        cnt++;
   4.633 -                        sig.append(ch);
   4.634 -                    } else {
   4.635 -                        hasReturnType[0] = true;
   4.636 -                        sig.insert(firstPos, ch);
   4.637 -                    }
   4.638 -                    continue;
   4.639 -                case 'V': 
   4.640 -                    assert !count;
   4.641 -                    hasReturnType[0] = false;
   4.642 -                    sig.insert(firstPos, 'V');
   4.643 -                    continue;
   4.644 -                case 'L':
   4.645 -                    int next = descriptor.indexOf(';', i);
   4.646 -                    if (count) {
   4.647 -                        cnt++;
   4.648 -                        sig.append(ch);
   4.649 -                        sig.append(descriptor.substring(i, next).replace('/', '_'));
   4.650 -                    } else {
   4.651 -                        sig.insert(firstPos, descriptor.substring(i, next).replace('/', '_'));
   4.652 -                        sig.insert(firstPos, ch);
   4.653 -                        hasReturnType[0] = true;
   4.654 -                    }
   4.655 -                    i = next + 1;
   4.656 -                    continue;
   4.657 -                case '[':
   4.658 -                    //arrays++;
   4.659 -                    continue;
   4.660 -                default:
   4.661 -                    break; // invalid character
   4.662 -            }
   4.663 -        }
   4.664 -        return cnt;
   4.665 -    }
   4.666 -
   4.667 -    private void generateStaticField(Variable v) throws IOException {
   4.668 -        out.append("\nvar ")
   4.669 -           .append(jc.getName().getInternalName().replace('/', '_'))
   4.670 -           .append('_').append(v.getName()).append(" = 0;");
   4.671 -    }
   4.672 -
   4.673 -    private String findMethodName(Method m) {
   4.674 -        StringBuilder tmp = new StringBuilder();
   4.675 -        if ("<init>".equals(m.getName())) { // NOI18N
   4.676 -            tmp.append("consV"); // NOI18N
   4.677 -        } else if ("<clinit>".equals(m.getName())) { // NOI18N
   4.678 -            tmp.append("classV"); // NOI18N
   4.679 -        } else {
   4.680 -            tmp.append(m.getName());
   4.681 -            outType(m.getReturnType(), tmp);
   4.682 -        } 
   4.683 -        List<Parameter> args = m.getParameters();
   4.684 -        for (Parameter t : args) {
   4.685 -            outType(t.getDescriptor(), tmp);
   4.686 -        }
   4.687 -        return tmp.toString();
   4.688 -    }
   4.689 -
   4.690 -    private String findMethodName(CPMethodInfo mi, int[] cnt, boolean[] hasReturn) {
   4.691 -        StringBuilder name = new StringBuilder();
   4.692 -        if ("<init>".equals(mi.getName())) { // NOI18N
   4.693 -            name.append("cons"); // NOI18N
   4.694 -        } else {
   4.695 -            name.append(mi.getName());
   4.696 -        }
   4.697 -        cnt[0] = countArgs(mi.getDescriptor(), hasReturn, name);
   4.698 -        return name.toString();
   4.699 -    }
   4.700 -
   4.701 -    private int invokeStaticMethod(byte[] byteCodes, int i, boolean isStatic)
   4.702 -    throws IOException {
   4.703 -        int methodIndex = readIntArg(byteCodes, i);
   4.704 -        CPMethodInfo mi = (CPMethodInfo) jc.getConstantPool().get(methodIndex);
   4.705 -        boolean[] hasReturn = { false };
   4.706 -        int[] cnt = { 0 };
   4.707 -        String mn = findMethodName(mi, cnt, hasReturn);
   4.708 -        out.append("{ ");
   4.709 -        for (int j = cnt[0] - 1; j >= 0; j--) {
   4.710 -            out.append("var v" + j).append(" = stack.pop(); ");
   4.711 -        }
   4.712 -        
   4.713 -        if (hasReturn[0]) {
   4.714 -            out.append("stack.push(");
   4.715 -        }
   4.716 -        final String in = mi.getClassName().getInternalName();
   4.717 -        out.append(in.replace('/', '_'));
   4.718 -        out.append('_');
   4.719 -        out.append(mn);
   4.720 -        out.append('(');
   4.721 -        String sep = "";
   4.722 -        if (!isStatic) {
   4.723 -            out.append("stack.pop()");
   4.724 -            sep = ", ";
   4.725 -        }
   4.726 -        for (int j = 0; j < cnt[0]; j++) {
   4.727 -            out.append(sep);
   4.728 -            out.append("v" + j);
   4.729 -            sep = ", ";
   4.730 -        }
   4.731 -        out.append(")");
   4.732 -        if (hasReturn[0]) {
   4.733 -            out.append(")");
   4.734 -        }
   4.735 -        out.append("; }");
   4.736 -        i += 2;
   4.737 -        addReference(in);
   4.738 -        return i;
   4.739 -    }
   4.740 -    private int invokeVirtualMethod(byte[] byteCodes, int i)
   4.741 -    throws IOException {
   4.742 -        int methodIndex = readIntArg(byteCodes, i);
   4.743 -        CPMethodInfo mi = (CPMethodInfo) jc.getConstantPool().get(methodIndex);
   4.744 -        boolean[] hasReturn = { false };
   4.745 -        int[] cnt = { 0 };
   4.746 -        String mn = findMethodName(mi, cnt, hasReturn);
   4.747 -        out.append("{ ");
   4.748 -        for (int j = cnt[0] - 1; j >= 0; j--) {
   4.749 -            out.append("var v" + j).append(" = stack.pop(); ");
   4.750 -        }
   4.751 -        out.append("var self = stack.pop(); ");
   4.752 -        if (hasReturn[0]) {
   4.753 -            out.append("stack.push(");
   4.754 -        }
   4.755 -        out.append("self.");
   4.756 -        out.append(mn);
   4.757 -        out.append('(');
   4.758 -        out.append("self");
   4.759 -        for (int j = 0; j < cnt[0]; j++) {
   4.760 -            out.append(", ");
   4.761 -            out.append("v" + j);
   4.762 -        }
   4.763 -        out.append(")");
   4.764 -        if (hasReturn[0]) {
   4.765 -            out.append(")");
   4.766 -        }
   4.767 -        out.append("; }");
   4.768 -        i += 2;
   4.769 -        return i;
   4.770 -    }
   4.771 -    
   4.772 -    private void addReference(String cn) {
   4.773 -        if (references != null) {
   4.774 -            references.add(cn);
   4.775 -        }
   4.776 -    }
   4.777 -
   4.778 -    private void outType(final String d, StringBuilder out) {
   4.779 -        if (d.charAt(0) == 'L') {
   4.780 -            assert d.charAt(d.length() - 1) == ';';
   4.781 -            out.append(d.replace('/', '_').substring(0, d.length() - 1));
   4.782 -        } else {
   4.783 -            out.append(d);
   4.784 -        }
   4.785 -    }
   4.786 -
   4.787 -    private String encodeConstant(CPEntry entry) {
   4.788 -        final String v;
   4.789 -        if (entry instanceof CPStringInfo) {
   4.790 -            v = "\"" + entry.getValue().toString().replace("\"", "\\\"") + "\"";
   4.791 -        } else {
   4.792 -            v = entry.getValue().toString();
   4.793 -        }
   4.794 -        return v;
   4.795 -    }
   4.796 -}
     5.1 --- a/src/test/java/org/apidesign/java4browser/Array.java	Mon Sep 24 09:35:00 2012 +0200
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,76 +0,0 @@
     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 -/**
    5.24 - *
    5.25 - * @author Jaroslav Tulach <jtulach@netbeans.org>
    5.26 - */
    5.27 -public class Array {
    5.28 -    byte[] bytes = { 1 };
    5.29 -    short[] shorts = { 2, 3 };
    5.30 -    int[] ints = { 4, 5, 6 };
    5.31 -    float[] floats = { 7, 8, 9, 10 };
    5.32 -    double[][] doubles = { {11}, {12}, {13}, {14}, {15} };
    5.33 -    char[] chars = { 'a', 'b' };
    5.34 -    
    5.35 -    private Array() {
    5.36 -    }
    5.37 -    
    5.38 -    byte bytes() {
    5.39 -        return bytes[0];
    5.40 -    }
    5.41 -    short shorts() {
    5.42 -        return shorts[1];
    5.43 -    }
    5.44 -    
    5.45 -    int ints() {
    5.46 -        return ints[2];
    5.47 -    }
    5.48 -    
    5.49 -    float floats() {
    5.50 -        return floats[3];
    5.51 -    }
    5.52 -    
    5.53 -    double doubles() {
    5.54 -        return doubles[4][0];
    5.55 -    }
    5.56 -    
    5.57 -    private static final Array[] ARR = { new Array(), new Array(), new Array() };
    5.58 -    
    5.59 -    public static double sum() {
    5.60 -        double sum = 0.0;
    5.61 -        for (int i = 0; i < ARR.length; i++) {
    5.62 -            sum += ARR[i].bytes();
    5.63 -            sum += ARR[i].shorts();
    5.64 -            sum += ARR[i].ints();
    5.65 -            sum += ARR[i].floats();
    5.66 -            sum += ARR[i].doubles();
    5.67 -        }
    5.68 -        return sum;
    5.69 -    }
    5.70 -    public static int simple() {
    5.71 -        int[] arr = { 0, 1, 2, 3, 4, 5 };
    5.72 -        
    5.73 -        int sum = 0;
    5.74 -        for (int i = 0; i < arr.length; i++) {
    5.75 -            sum += arr[i];
    5.76 -        }
    5.77 -        return sum;
    5.78 -    }
    5.79 -}
     6.1 --- a/src/test/java/org/apidesign/java4browser/ArrayTest.java	Mon Sep 24 09:35:00 2012 +0200
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,63 +0,0 @@
     6.4 -/*
     6.5 -Java 4 Browser Bytecode Translator
     6.6 -Copyright (C) 2012-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 -package org.apidesign.java4browser;
    6.22 -
    6.23 -import javax.script.Invocable;
    6.24 -import javax.script.ScriptException;
    6.25 -import org.testng.annotations.Test;
    6.26 -import static org.testng.Assert.*;
    6.27 -
    6.28 -/**
    6.29 - *
    6.30 - * @author Jaroslav Tulach <jtulach@netbeans.org>
    6.31 - */
    6.32 -public class ArrayTest {
    6.33 -    @Test public void verifySimpleIntOperation() throws Exception {
    6.34 -        assertExec("CheckTheSum", "org_apidesign_java4browser_Array_simpleI", 
    6.35 -            Double.valueOf(15)
    6.36 -        );
    6.37 -    }
    6.38 -    @Test public void verifyOperationsOnArrays() throws Exception {
    6.39 -        assertExec("The sum is 105", "org_apidesign_java4browser_Array_sumD", 
    6.40 -            Double.valueOf(105)
    6.41 -        );
    6.42 -    }
    6.43 -    
    6.44 -    private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception {
    6.45 -        StringBuilder sb = new StringBuilder();
    6.46 -        Invocable i = StaticMethodTest.compileClass(sb, 
    6.47 -            "org/apidesign/java4browser/Array"
    6.48 -        );
    6.49 -        
    6.50 -        Object ret = null;
    6.51 -        try {
    6.52 -            ret = i.invokeFunction(methodName, args);
    6.53 -        } catch (ScriptException ex) {
    6.54 -            fail("Execution failed in " + sb, ex);
    6.55 -        } catch (NoSuchMethodException ex) {
    6.56 -            fail("Cannot find method in " + sb, ex);
    6.57 -        }
    6.58 -        if (ret == null && expRes == null) {
    6.59 -            return;
    6.60 -        }
    6.61 -        if (expRes.equals(ret)) {
    6.62 -            return;
    6.63 -        }
    6.64 -        assertEquals(ret, expRes, msg + "was: " + ret + "\n" + sb);
    6.65 -    }
    6.66 -}
     7.1 --- a/src/test/java/org/apidesign/java4browser/GetByte.java	Mon Sep 24 09:35:00 2012 +0200
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,9 +0,0 @@
     7.4 -/*
     7.5 - * To change this template, choose Tools | Templates
     7.6 - * and open the template in the editor.
     7.7 - */
     7.8 -package org.apidesign.java4browser;
     7.9 -
    7.10 -public interface GetByte {
    7.11 -    public byte getByte();
    7.12 -}
     8.1 --- a/src/test/java/org/apidesign/java4browser/Instance.java	Mon Sep 24 09:35:00 2012 +0200
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,69 +0,0 @@
     8.4 -/*
     8.5 - * To change this template, choose Tools | Templates
     8.6 - * and open the template in the editor.
     8.7 - */
     8.8 -package org.apidesign.java4browser;
     8.9 -
    8.10 -/**
    8.11 - *
    8.12 - * @author Jaroslav Tulach <jtulach@netbeans.org>
    8.13 - */
    8.14 -public class Instance {
    8.15 -    private int i;
    8.16 -    protected short s;
    8.17 -    public double d;
    8.18 -    private float f;
    8.19 -    protected byte b = (byte)31;
    8.20 -    
    8.21 -    private Instance() {
    8.22 -    }
    8.23 -
    8.24 -    public Instance(int i, double d) {
    8.25 -        this.i = i;
    8.26 -        this.d = d;
    8.27 -    }
    8.28 -    public byte getByte() {
    8.29 -        return b;
    8.30 -    }
    8.31 -    
    8.32 -    public void setByte(byte b) {
    8.33 -        this.b = b;
    8.34 -    }
    8.35 -    public static double defaultDblValue() {
    8.36 -        Instance create = new Instance();
    8.37 -        return create.d;
    8.38 -    }
    8.39 -    
    8.40 -    public static byte assignedByteValue() {
    8.41 -        return new Instance().b;
    8.42 -    }
    8.43 -    public static double magicOne() {
    8.44 -        Instance i = new Instance(10, 3.3d);
    8.45 -        i.b = (byte)0x09;
    8.46 -        return (i.i - i.b) * i.d;
    8.47 -    }
    8.48 -    public static int virtualBytes() {
    8.49 -        Instance i = new InstanceSub(7, 2.2d);
    8.50 -        i.setByte((byte)0x0a);
    8.51 -        Instance i2 = new Instance(3, 333.0d);
    8.52 -        i2.setByte((byte)44);
    8.53 -        return i.getByte() + i2.getByte();
    8.54 -    }
    8.55 -    public static float interfaceBytes() {
    8.56 -        GetByte i = new InstanceSub(7, 2.2d);
    8.57 -        return i.getByte();
    8.58 -    }
    8.59 -    public static boolean instanceOf(boolean sub) {
    8.60 -        Instance i = createInstance(sub);
    8.61 -        return isInstanceSubOf(i);
    8.62 -    }
    8.63 -    private static boolean isInstanceSubOf(Instance instance) {
    8.64 -        return instance instanceof InstanceSub;
    8.65 -    }
    8.66 -    private static Instance createInstance(boolean sub) {
    8.67 -        return sub ? new InstanceSub(3, 0) : new Instance();
    8.68 -    }
    8.69 -    private static boolean isNull() {
    8.70 -        return createInstance(true) == null;
    8.71 -    }
    8.72 -}
     9.1 --- a/src/test/java/org/apidesign/java4browser/InstanceSub.java	Mon Sep 24 09:35:00 2012 +0200
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,20 +0,0 @@
     9.4 -/*
     9.5 - * To change this template, choose Tools | Templates
     9.6 - * and open the template in the editor.
     9.7 - */
     9.8 -package org.apidesign.java4browser;
     9.9 -
    9.10 -/**
    9.11 - *
    9.12 - * @author Jaroslav Tulach <jtulach@netbeans.org>
    9.13 - */
    9.14 -public class InstanceSub extends Instance implements GetByte {
    9.15 -    public InstanceSub(int i, double d) {
    9.16 -        super(i, d);
    9.17 -    }
    9.18 -    
    9.19 -    @Override
    9.20 -    public void setByte(byte b) {
    9.21 -        super.setByte((byte) (b + 1));
    9.22 -    }
    9.23 -}
    10.1 --- a/src/test/java/org/apidesign/java4browser/InstanceTest.java	Mon Sep 24 09:35:00 2012 +0200
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,101 +0,0 @@
    10.4 -/*
    10.5 - * To change this template, choose Tools | Templates
    10.6 - * and open the template in the editor.
    10.7 - */
    10.8 -package org.apidesign.java4browser;
    10.9 -
   10.10 -import javax.script.Invocable;
   10.11 -import javax.script.ScriptException;
   10.12 -import org.testng.annotations.Test;
   10.13 -import static org.testng.Assert.*;
   10.14 -
   10.15 -/**
   10.16 - *
   10.17 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   10.18 - */
   10.19 -public class InstanceTest {
   10.20 -    @Test public void verifyDefaultDoubleValue() throws Exception {
   10.21 -        assertExec(
   10.22 -            "Will be zero",
   10.23 -            "org_apidesign_java4browser_Instance_defaultDblValueD",
   10.24 -            Double.valueOf(0)
   10.25 -        );
   10.26 -    }
   10.27 -    @Test public void verifyAssignedByteValue() throws Exception {
   10.28 -        assertExec(
   10.29 -            "Will one thirty one",
   10.30 -            "org_apidesign_java4browser_Instance_assignedByteValueB",
   10.31 -            Double.valueOf(31)
   10.32 -        );
   10.33 -    }
   10.34 -    @Test public void verifyMagicOne() throws Exception {
   10.35 -        assertExec(
   10.36 -            "Should be three and something",
   10.37 -            "org_apidesign_java4browser_Instance_magicOneD",
   10.38 -            Double.valueOf(3.3)
   10.39 -        );
   10.40 -    }
   10.41 -    @Test public void verifyInstanceMethods() throws Exception {
   10.42 -        assertExec(
   10.43 -            "Should be eleven as we invoke overwritten method, plus 44",
   10.44 -            "org_apidesign_java4browser_Instance_virtualBytesI",
   10.45 -            Double.valueOf(55)
   10.46 -        );
   10.47 -    }
   10.48 -    @Test public void verifyInterfaceMethods() throws Exception {
   10.49 -        assertExec(
   10.50 -            "Retruns default value",
   10.51 -            "org_apidesign_java4browser_Instance_interfaceBytesF",
   10.52 -            Double.valueOf(31)
   10.53 -        );
   10.54 -    }
   10.55 -
   10.56 -    @Test public void isNull() throws Exception {
   10.57 -        assertExec(
   10.58 -            "Yes, we are instance",
   10.59 -            "org_apidesign_java4browser_Instance_isNullZ",
   10.60 -            Double.valueOf(0.0)
   10.61 -        );
   10.62 -    }
   10.63 -
   10.64 -    @Test public void isInstanceOf() throws Exception {
   10.65 -        assertExec(
   10.66 -            "Yes, we are instance",
   10.67 -            "org_apidesign_java4browser_Instance_instanceOfZZ",
   10.68 -            Double.valueOf(1.0), true
   10.69 -        );
   10.70 -    }
   10.71 -
   10.72 -    @Test public void notInstanceOf() throws Exception {
   10.73 -        assertExec(
   10.74 -            "No, we are not an instance",
   10.75 -            "org_apidesign_java4browser_Instance_instanceOfZZ",
   10.76 -            Double.valueOf(0.0), false
   10.77 -        );
   10.78 -    }
   10.79 -    
   10.80 -    private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception {
   10.81 -        StringBuilder sb = new StringBuilder();
   10.82 -        Invocable i = StaticMethodTest.compileClass(sb, 
   10.83 -            "org/apidesign/java4browser/Instance"
   10.84 -        );
   10.85 -        
   10.86 -        Object ret = null;
   10.87 -        try {
   10.88 -            ret = i.invokeFunction(methodName, args);
   10.89 -        } catch (ScriptException ex) {
   10.90 -            fail("Execution failed in " + sb, ex);
   10.91 -        } catch (NoSuchMethodException ex) {
   10.92 -            fail("Cannot find method in " + sb, ex);
   10.93 -        }
   10.94 -        if (ret == null && expRes == null) {
   10.95 -            return;
   10.96 -        }
   10.97 -        if (expRes.equals(ret)) {
   10.98 -            return;
   10.99 -        }
  10.100 -        assertEquals(ret, expRes, msg + "was: " + ret + "\n" + sb);
  10.101 -        
  10.102 -    }
  10.103 -    
  10.104 -}
    11.1 --- a/src/test/java/org/apidesign/java4browser/StaticMethod.java	Mon Sep 24 09:35:00 2012 +0200
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,68 +0,0 @@
    11.4 -/*
    11.5 -Java 4 Browser Bytecode Translator
    11.6 -Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    11.7 -
    11.8 -This program is free software: you can redistribute it and/or modify
    11.9 -it under the terms of the GNU General Public License as published by
   11.10 -the Free Software Foundation, version 2 of the License.
   11.11 -
   11.12 -This program is distributed in the hope that it will be useful,
   11.13 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   11.14 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11.15 -GNU General Public License for more details.
   11.16 -
   11.17 -You should have received a copy of the GNU General Public License
   11.18 -along with this program. Look for COPYING file in the top folder.
   11.19 -If not, see http://opensource.org/licenses/GPL-2.0.
   11.20 -*/
   11.21 -package org.apidesign.java4browser;
   11.22 -
   11.23 -/**
   11.24 - *
   11.25 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   11.26 - */
   11.27 -public class StaticMethod {
   11.28 -    private static int cnt;
   11.29 -    
   11.30 -    public static int sum(int x, int y) {
   11.31 -        return x + y;
   11.32 -    }
   11.33 -    public static float power(float x) {
   11.34 -        return x * x;
   11.35 -    }
   11.36 -    public static double minus(double x, long y) {
   11.37 -        return x - y;
   11.38 -    }
   11.39 -    public static int div(byte c, double d) {
   11.40 -        return (int)(d / c);
   11.41 -    }
   11.42 -    public static int mix(int a, long b, byte c, double d) {
   11.43 -        return (int)((b / a + c) * d);
   11.44 -    }
   11.45 -    public static long xor(int a, long b) {
   11.46 -        return a ^ b;
   11.47 -    }
   11.48 -    public static long orOrAnd(boolean doOr, int a, int b) {
   11.49 -        return doOr ? a | b : a & b;
   11.50 -    }
   11.51 -    public static long factRec(int n) {
   11.52 -        if (n <= 1) {
   11.53 -            return 1;
   11.54 -        } else {
   11.55 -            return n * factRec(n - 1);
   11.56 -        }
   11.57 -    }
   11.58 -    public static long factIter(int n) {
   11.59 -        long res = 1;
   11.60 -        for (int i = 2; i <= n; i++) {
   11.61 -            res *= i;
   11.62 -        }
   11.63 -        return res;
   11.64 -    }
   11.65 -    public static int inc4() {
   11.66 -        cnt++;
   11.67 -        cnt+=2;
   11.68 -        cnt++;
   11.69 -        return cnt;
   11.70 -    }
   11.71 -}
    12.1 --- a/src/test/java/org/apidesign/java4browser/StaticMethodTest.java	Mon Sep 24 09:35:00 2012 +0200
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,201 +0,0 @@
    12.4 -/*
    12.5 -Java 4 Browser Bytecode Translator
    12.6 -Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    12.7 -
    12.8 -This program is free software: you can redistribute it and/or modify
    12.9 -it under the terms of the GNU General Public License as published by
   12.10 -the Free Software Foundation, version 2 of the License.
   12.11 -
   12.12 -This program is distributed in the hope that it will be useful,
   12.13 -but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.14 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.15 -GNU General Public License for more details.
   12.16 -
   12.17 -You should have received a copy of the GNU General Public License
   12.18 -along with this program. Look for COPYING file in the top folder.
   12.19 -If not, see http://opensource.org/licenses/GPL-2.0.
   12.20 -*/
   12.21 -package org.apidesign.java4browser;
   12.22 -
   12.23 -import java.io.IOException;
   12.24 -import java.io.InputStream;
   12.25 -import java.util.Arrays;
   12.26 -import java.util.HashSet;
   12.27 -import java.util.Iterator;
   12.28 -import java.util.LinkedList;
   12.29 -import java.util.Set;
   12.30 -import java.util.TreeSet;
   12.31 -import javax.script.Invocable;
   12.32 -import javax.script.ScriptEngine;
   12.33 -import javax.script.ScriptEngineManager;
   12.34 -import javax.script.ScriptException;
   12.35 -import static org.testng.Assert.*;
   12.36 -import org.testng.annotations.Test;
   12.37 -
   12.38 -/** Checks the basic behavior of the translator.
   12.39 - *
   12.40 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   12.41 - */
   12.42 -public class StaticMethodTest {
   12.43 -    @Test public void threePlusFour() throws Exception {
   12.44 -        assertExec(
   12.45 -            "Should be seven", 
   12.46 -            "org_apidesign_java4browser_StaticMethod_sumIII", 
   12.47 -            Double.valueOf(7), 
   12.48 -            3, 4
   12.49 -        );
   12.50 -    }
   12.51 -
   12.52 -    @Test public void powerOfThree() throws Exception {
   12.53 -        assertExec(
   12.54 -            "Should be nine", 
   12.55 -            "org_apidesign_java4browser_StaticMethod_powerFF", 
   12.56 -            Double.valueOf(9),
   12.57 -            3.0f
   12.58 -        );
   12.59 -    }
   12.60 -
   12.61 -    @Test public void doubleWithoutLong() throws Exception {
   12.62 -        assertExec(
   12.63 -            "Should be two",
   12.64 -            "org_apidesign_java4browser_StaticMethod_minusDDJ", 
   12.65 -            Double.valueOf(2),
   12.66 -            3.0d, 1l
   12.67 -        );
   12.68 -    }
   12.69 -
   12.70 -    @Test public void divAndRound() throws Exception {
   12.71 -        assertExec(
   12.72 -            "Should be rounded to one",
   12.73 -            "org_apidesign_java4browser_StaticMethod_divIBD", 
   12.74 -            Double.valueOf(1),
   12.75 -            3, 3.75
   12.76 -        );
   12.77 -    }
   12.78 -    @Test public void mixedMethodFourParams() throws Exception {
   12.79 -        assertExec(
   12.80 -            "Should be two",
   12.81 -            "org_apidesign_java4browser_StaticMethod_mixIIJBD", 
   12.82 -            Double.valueOf(20),
   12.83 -            2, 10l, 5, 2.0
   12.84 -        );
   12.85 -    }
   12.86 -    @Test public void factRec() throws Exception {
   12.87 -        assertExec(
   12.88 -            "Factorial of 5 is 120",
   12.89 -            "org_apidesign_java4browser_StaticMethod_factRecJI", 
   12.90 -            Double.valueOf(120),
   12.91 -            5
   12.92 -        );
   12.93 -    }
   12.94 -    @Test public void factIter() throws Exception {
   12.95 -        assertExec(
   12.96 -            "Factorial of 5 is 120",
   12.97 -            "org_apidesign_java4browser_StaticMethod_factIterJI", 
   12.98 -            Double.valueOf(120),
   12.99 -            5
  12.100 -        );
  12.101 -    }
  12.102 -    
  12.103 -    @Test public void xor() throws Exception {
  12.104 -        assertExec(
  12.105 -            "Xor is 4",
  12.106 -            "org_apidesign_java4browser_StaticMethod_xorJIJ",
  12.107 -            Double.valueOf(4),
  12.108 -            7,
  12.109 -            3
  12.110 -        );
  12.111 -    }
  12.112 -    
  12.113 -    @Test public void or() throws Exception {
  12.114 -        assertExec(
  12.115 -            "Or will be 7",
  12.116 -            "org_apidesign_java4browser_StaticMethod_orOrAndJZII",
  12.117 -            Double.valueOf(7),
  12.118 -            true,
  12.119 -            4,
  12.120 -            3
  12.121 -        );
  12.122 -    }
  12.123 -    @Test public void and() throws Exception {
  12.124 -        assertExec(
  12.125 -            "And will be 3",
  12.126 -            "org_apidesign_java4browser_StaticMethod_orOrAndJZII",
  12.127 -            Double.valueOf(3),
  12.128 -            false,
  12.129 -            7,
  12.130 -            3
  12.131 -        );
  12.132 -    }
  12.133 -    @Test public void inc4() throws Exception {
  12.134 -        assertExec(
  12.135 -            "It will be 4",
  12.136 -            "org_apidesign_java4browser_StaticMethod_inc4I",
  12.137 -            Double.valueOf(4)
  12.138 -        );
  12.139 -    }
  12.140 -    
  12.141 -    private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception {
  12.142 -        StringBuilder sb = new StringBuilder();
  12.143 -        Invocable i = compileClass(sb, "org/apidesign/java4browser/StaticMethod");
  12.144 -        
  12.145 -        Object ret = null;
  12.146 -        try {
  12.147 -            ret = i.invokeFunction(methodName, args);
  12.148 -        } catch (ScriptException ex) {
  12.149 -            fail("Execution failed in " + sb, ex);
  12.150 -        } catch (NoSuchMethodException ex) {
  12.151 -            fail("Cannot find method in " + sb, ex);
  12.152 -        }
  12.153 -        if (ret == null && expRes == null) {
  12.154 -            return;
  12.155 -        }
  12.156 -        if (expRes.equals(ret)) {
  12.157 -            return;
  12.158 -        }
  12.159 -        assertEquals(ret, expRes, msg + "was: " + ret + "\n" + sb);
  12.160 -        
  12.161 -    }
  12.162 -
  12.163 -    static Invocable compileClass(StringBuilder sb, String... names) throws ScriptException, IOException {
  12.164 -        if (sb == null) {
  12.165 -            sb = new StringBuilder();
  12.166 -        }
  12.167 -        Set<String> processed = new HashSet<String>();
  12.168 -
  12.169 -        LinkedList<String> toProcess = new LinkedList<String>(Arrays.asList(names));
  12.170 -        for (;;) {
  12.171 -            toProcess.removeAll(processed);
  12.172 -            if (toProcess.isEmpty()) {
  12.173 -                break;
  12.174 -            }
  12.175 -            String name = toProcess.getFirst();
  12.176 -            processed.add(name);
  12.177 -            if (name.startsWith("java/") && !name.equals("java/lang/Object")) {
  12.178 -                continue;
  12.179 -            }
  12.180 -            InputStream is = StaticMethodTest.class.getClassLoader().getResourceAsStream(name + ".class");
  12.181 -            assertNotNull(is, "Class file found");
  12.182 -            try {
  12.183 -                ByteCodeToJavaScript.compile(is, sb, toProcess);
  12.184 -            } catch (RuntimeException ex) {
  12.185 -                int lastBlock = sb.lastIndexOf("{");
  12.186 -                throw new IllegalStateException(
  12.187 -                    "Error while compiling " + name + "\n" + 
  12.188 -                    sb.substring(0, sb.length()), 
  12.189 -                    ex
  12.190 -                );
  12.191 -            }
  12.192 -        }
  12.193 -        ScriptEngineManager sem = new ScriptEngineManager();
  12.194 -        ScriptEngine js = sem.getEngineByExtension("js");
  12.195 -        try {
  12.196 -            Object res = js.eval(sb.toString());
  12.197 -            assertTrue(js instanceof Invocable, "It is invocable object: " + res);
  12.198 -            return (Invocable)js;
  12.199 -        } catch (ScriptException ex) {
  12.200 -            fail("Could not compile:\n" + sb, ex);
  12.201 -            return null;
  12.202 -        }
  12.203 -    }
  12.204 -}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/vm/nb-configuration.xml	Mon Sep 24 11:07:38 2012 +0200
    13.3 @@ -0,0 +1,18 @@
    13.4 +<?xml version="1.0" encoding="UTF-8"?>
    13.5 +<project-shared-configuration>
    13.6 +    <!--
    13.7 +This file contains additional configuration written by modules in the NetBeans IDE.
    13.8 +The configuration is intended to be shared among all the users of project and
    13.9 +therefore it is assumed to be part of version control checkout.
   13.10 +Without this configuration present, some functionality in the IDE may be limited or fail altogether.
   13.11 +-->
   13.12 +    <properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
   13.13 +        <!--
   13.14 +Properties that influence various parts of the IDE, especially code formatting and the like. 
   13.15 +You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
   13.16 +That way multiple projects can share the same settings (useful for formatting rules for example).
   13.17 +Any value defined here will override the pom.xml file value but is only applicable to the current project.
   13.18 +-->
   13.19 +        <netbeans.compile.on.save>all</netbeans.compile.on.save>
   13.20 +    </properties>
   13.21 +</project-shared-configuration>
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/vm/pom.xml	Mon Sep 24 11:07:38 2012 +0200
    14.3 @@ -0,0 +1,75 @@
    14.4 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    14.5 +  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    14.6 +  <modelVersion>4.0.0</modelVersion>
    14.7 +
    14.8 +  <groupId>org.apidesign</groupId>
    14.9 +  <artifactId>vm4brwsr</artifactId>
   14.10 +  <version>0.1-SNAPSHOT</version>
   14.11 +  <packaging>jar</packaging>
   14.12 +
   14.13 +  <name>Java VM for Browser</name>
   14.14 +  <url>http://bck2brwsr.apidesign.org</url>
   14.15 +
   14.16 +  <properties>
   14.17 +    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   14.18 +    <author.name>Jaroslav Tulach</author.name>
   14.19 +    <author.email>jaroslav.tulach@apidesign.org</author.email>
   14.20 +  </properties>
   14.21 +  
   14.22 +  <repositories>
   14.23 +      <repository>
   14.24 +          <id>netbeans</id>
   14.25 +          <name>NetBeans</name>
   14.26 +          <url>http://bits.netbeans.org/maven2/</url>
   14.27 +      </repository>
   14.28 +  </repositories>
   14.29 +  <pluginRepositories>
   14.30 +    <pluginRepository>
   14.31 +        <id>mc-release</id>
   14.32 +        <name>Local Maven repository of releases</name>
   14.33 +        <url>http://mc-repo.googlecode.com/svn/maven2/releases</url>
   14.34 +        <snapshots>
   14.35 +            <enabled>false</enabled>
   14.36 +        </snapshots>
   14.37 +        <releases>
   14.38 +            <enabled>true</enabled>
   14.39 +        </releases>
   14.40 +    </pluginRepository>
   14.41 +  </pluginRepositories>
   14.42 +  <scm>
   14.43 +      <connection>scm:hg:http://source.apidesign.org/hg/bck2brwsr</connection>
   14.44 +      <url>http://source.apidesign.org/hg/bck2brwsr</url>
   14.45 +  </scm>
   14.46 +    <build>
   14.47 +        <plugins>
   14.48 +            <plugin>
   14.49 +                <groupId>com.mycila.maven-license-plugin</groupId>
   14.50 +                <artifactId>maven-license-plugin</artifactId>
   14.51 +                <version>1.9.0</version>
   14.52 +                <configuration>
   14.53 +                    <header>src/header.txt</header>
   14.54 +                </configuration>
   14.55 +            </plugin>
   14.56 +        </plugins>
   14.57 +    </build>
   14.58 +  <dependencies>
   14.59 +    <dependency>
   14.60 +      <groupId>org.testng</groupId>
   14.61 +      <artifactId>testng</artifactId>
   14.62 +      <version>6.7</version>
   14.63 +      <scope>test</scope>
   14.64 +      <exclusions>
   14.65 +        <exclusion>
   14.66 +          <artifactId>junit</artifactId>
   14.67 +          <groupId>junit</groupId>
   14.68 +        </exclusion>
   14.69 +      </exclusions>
   14.70 +    </dependency>
   14.71 +    <dependency>
   14.72 +      <groupId>org.netbeans.api</groupId>
   14.73 +      <artifactId>org-netbeans-modules-classfile</artifactId>
   14.74 +      <version>RELEASE72</version>
   14.75 +      <type>jar</type>
   14.76 +    </dependency>
   14.77 +  </dependencies>
   14.78 +</project>
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/vm/src/header.txt	Mon Sep 24 11:07:38 2012 +0200
    15.3 @@ -0,0 +1,15 @@
    15.4 +Java 4 Browser Bytecode Translator
    15.5 +Copyright (C) 2012-${year} Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    15.6 +
    15.7 +This program is free software: you can redistribute it and/or modify
    15.8 +it under the terms of the GNU General Public License as published by
    15.9 +the Free Software Foundation, version 2 of the License.
   15.10 +
   15.11 +This program is distributed in the hope that it will be useful,
   15.12 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.13 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.14 +GNU General Public License for more details.
   15.15 +
   15.16 +You should have received a copy of the GNU General Public License
   15.17 +along with this program. Look for COPYING file in the top folder.
   15.18 +If not, see http://opensource.org/licenses/GPL-2.0.
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Mon Sep 24 11:07:38 2012 +0200
    16.3 @@ -0,0 +1,793 @@
    16.4 +/*
    16.5 +Java 4 Browser Bytecode Translator
    16.6 +Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    16.7 +
    16.8 +This program is free software: you can redistribute it and/or modify
    16.9 +it under the terms of the GNU General Public License as published by
   16.10 +the Free Software Foundation, version 2 of the License.
   16.11 +
   16.12 +This program is distributed in the hope that it will be useful,
   16.13 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.14 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.15 +GNU General Public License for more details.
   16.16 +
   16.17 +You should have received a copy of the GNU General Public License
   16.18 +along with this program. Look for COPYING file in the top folder.
   16.19 +If not, see http://opensource.org/licenses/GPL-2.0.
   16.20 +*/
   16.21 +package org.apidesign.vm4brwsr;
   16.22 +
   16.23 +import java.io.IOException;
   16.24 +import java.io.InputStream;
   16.25 +import java.util.ArrayList;
   16.26 +import java.util.Collection;
   16.27 +import java.util.List;
   16.28 +import static org.netbeans.modules.classfile.ByteCodes.*;
   16.29 +import org.netbeans.modules.classfile.CPClassInfo;
   16.30 +import org.netbeans.modules.classfile.CPEntry;
   16.31 +import org.netbeans.modules.classfile.CPFieldInfo;
   16.32 +import org.netbeans.modules.classfile.CPMethodInfo;
   16.33 +import org.netbeans.modules.classfile.CPStringInfo;
   16.34 +import org.netbeans.modules.classfile.ClassFile;
   16.35 +import org.netbeans.modules.classfile.ClassName;
   16.36 +import org.netbeans.modules.classfile.Code;
   16.37 +import org.netbeans.modules.classfile.Method;
   16.38 +import org.netbeans.modules.classfile.Parameter;
   16.39 +import org.netbeans.modules.classfile.Variable;
   16.40 +
   16.41 +/** Translator of the code inside class files to JavaScript.
   16.42 + *
   16.43 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   16.44 + */
   16.45 +public final class ByteCodeToJavaScript {
   16.46 +    private final ClassFile jc;
   16.47 +    private final Appendable out;
   16.48 +    private final Collection<? super String> references;
   16.49 +
   16.50 +    private ByteCodeToJavaScript(
   16.51 +        ClassFile jc, Appendable out, Collection<? super String> references
   16.52 +    ) {
   16.53 +        this.jc = jc;
   16.54 +        this.out = out;
   16.55 +        this.references = references;
   16.56 +    }
   16.57 +
   16.58 +    /**
   16.59 +     * Converts a given class file to a JavaScript version.
   16.60 +     *
   16.61 +     * @param classFile input stream with code of the .class file
   16.62 +     * @param out a {@link StringBuilder} or similar to generate the output to
   16.63 +     * @param references a write only collection where the system adds list of
   16.64 +     *   other classes that were referenced and should be loaded in order the
   16.65 +     *   generated JavaScript code works properly. The names are in internal 
   16.66 +     *   JVM form so String is <code>java/lang/String</code>. Can be <code>null</code>
   16.67 +     *   if one is not interested in knowing references
   16.68 +     * @throws IOException if something goes wrong during read or write or translating
   16.69 +     */
   16.70 +    
   16.71 +    public static void compile(
   16.72 +        InputStream classFile, Appendable out,
   16.73 +        Collection<? super String> references
   16.74 +    ) throws IOException {
   16.75 +        ClassFile jc = new ClassFile(classFile, true);
   16.76 +        ByteCodeToJavaScript compiler = new ByteCodeToJavaScript(
   16.77 +            jc, out, references
   16.78 +        );
   16.79 +        List<String> toInitilize = new ArrayList<String>();
   16.80 +        for (Method m : jc.getMethods()) {
   16.81 +            if (m.isStatic()) {
   16.82 +                compiler.generateStaticMethod(m, toInitilize);
   16.83 +            } else {
   16.84 +                compiler.generateInstanceMethod(m);
   16.85 +            }
   16.86 +        }
   16.87 +        for (Variable v : jc.getVariables()) {
   16.88 +            if (v.isStatic()) {
   16.89 +                compiler.generateStaticField(v);
   16.90 +            }
   16.91 +        }
   16.92 +        
   16.93 +        final String className = jc.getName().getInternalName().replace('/', '_');
   16.94 +        out.append("\nfunction ").append(className);
   16.95 +        out.append("() {");
   16.96 +        for (Method m : jc.getMethods()) {
   16.97 +            if (!m.isStatic()) {
   16.98 +                compiler.generateMethodReference(m);
   16.99 +            }
  16.100 +        }
  16.101 +        for (Variable v : jc.getVariables()) {
  16.102 +            if (!v.isStatic()) {
  16.103 +                out.append("\n  this." + v.getName() + " = 0;");
  16.104 +            }
  16.105 +        }
  16.106 +        out.append("\n  this.$instOf_").append(className).append(" = true;");
  16.107 +        out.append("\n}");
  16.108 +        ClassName sc = jc.getSuperClass();
  16.109 +        if (sc != null) {
  16.110 +            out.append("\n").append(className)
  16.111 +               .append(".prototype = new ").append(sc.getInternalName().replace('/', '_'));
  16.112 +        }
  16.113 +        for (String init : toInitilize) {
  16.114 +            out.append("\n").append(init).append("();");
  16.115 +        }
  16.116 +    }
  16.117 +    private void generateStaticMethod(Method m, List<String> toInitilize) throws IOException {
  16.118 +        final String mn = findMethodName(m);
  16.119 +        out.append("\nfunction ").append(
  16.120 +            jc.getName().getInternalName().replace('/', '_')
  16.121 +        ).append('_').append(mn);
  16.122 +        if (mn.equals("classV")) {
  16.123 +            toInitilize.add(jc.getName().getInternalName().replace('/', '_') + '_' + mn);
  16.124 +        }
  16.125 +        out.append('(');
  16.126 +        String space = "";
  16.127 +        List<Parameter> args = m.getParameters();
  16.128 +        for (int index = 0, i = 0; i < args.size(); i++) {
  16.129 +            out.append(space);
  16.130 +            out.append("arg").append(String.valueOf(index));
  16.131 +            space = ",";
  16.132 +            final String desc = args.get(i).getDescriptor();
  16.133 +            if ("D".equals(desc) || "J".equals(desc)) {
  16.134 +                index += 2;
  16.135 +            } else {
  16.136 +                index++;
  16.137 +            }
  16.138 +        }
  16.139 +        out.append(") {").append("\n");
  16.140 +        final Code code = m.getCode();
  16.141 +        if (code != null) {
  16.142 +            int len = code.getMaxLocals();
  16.143 +            for (int index = args.size(), i = args.size(); i < len; i++) {
  16.144 +                out.append("  var ");
  16.145 +                out.append("arg").append(String.valueOf(i)).append(";\n");
  16.146 +            }
  16.147 +            out.append("  var stack = new Array();\n");
  16.148 +            produceCode(code.getByteCodes());
  16.149 +        } else {
  16.150 +            out.append("  /* no code found for ").append(m.getTypeSignature()).append(" */\n");
  16.151 +        }
  16.152 +        out.append("}");
  16.153 +    }
  16.154 +    
  16.155 +    private void generateMethodReference(Method m) throws IOException {
  16.156 +        final String name = findMethodName(m);
  16.157 +        out.append("\n  this.").append(name).append(" = ")
  16.158 +           .append(jc.getName().getInternalName().replace('/', '_'))
  16.159 +           .append('_').append(name).append(";");
  16.160 +    }
  16.161 +    
  16.162 +    private void generateInstanceMethod(Method m) throws IOException {
  16.163 +        out.append("\nfunction ").append(
  16.164 +            jc.getName().getInternalName().replace('/', '_')
  16.165 +        ).append('_').append(findMethodName(m));
  16.166 +        out.append("(arg0");
  16.167 +        String space = ",";
  16.168 +        List<Parameter> args = m.getParameters();
  16.169 +        for (int index = 1, i = 0; i < args.size(); i++) {
  16.170 +            out.append(space);
  16.171 +            out.append("arg").append(String.valueOf(index));
  16.172 +            final String desc = args.get(i).getDescriptor();
  16.173 +            if ("D".equals(desc) || "J".equals(desc)) {
  16.174 +                index += 2;
  16.175 +            } else {
  16.176 +                index++;
  16.177 +            }
  16.178 +        }
  16.179 +        out.append(") {").append("\n");
  16.180 +        final Code code = m.getCode();
  16.181 +        if (code != null) {
  16.182 +            int len = code.getMaxLocals();
  16.183 +            for (int index = args.size(), i = args.size(); i < len; i++) {
  16.184 +                out.append("  var ");
  16.185 +                out.append("arg").append(String.valueOf(i + 1)).append(";\n");
  16.186 +            }
  16.187 +            out.append(";\n  var stack = new Array(");
  16.188 +            out.append(Integer.toString(code.getMaxStack()));
  16.189 +            out.append(");\n");
  16.190 +            produceCode(code.getByteCodes());
  16.191 +        } else {
  16.192 +            out.append("  /* no code found for ").append(m.getTypeSignature()).append(" */\n");
  16.193 +        }
  16.194 +        out.append("}");
  16.195 +    }
  16.196 +
  16.197 +    private void produceCode(byte[] byteCodes) throws IOException {
  16.198 +        out.append("\n  var gt = 0;\n  for(;;) switch(gt) {\n");
  16.199 +        for (int i = 0; i < byteCodes.length; i++) {
  16.200 +            int prev = i;
  16.201 +            out.append("    case " + i).append(": ");
  16.202 +            final int c = (byteCodes[i] + 256) % 256;
  16.203 +            switch (c) {
  16.204 +                case bc_aload_0:
  16.205 +                case bc_iload_0:
  16.206 +                case bc_lload_0:
  16.207 +                case bc_fload_0:
  16.208 +                case bc_dload_0:
  16.209 +                    out.append("stack.push(arg0);");
  16.210 +                    break;
  16.211 +                case bc_aload_1:
  16.212 +                case bc_iload_1:
  16.213 +                case bc_lload_1:
  16.214 +                case bc_fload_1:
  16.215 +                case bc_dload_1:
  16.216 +                    out.append("stack.push(arg1);");
  16.217 +                    break;
  16.218 +                case bc_aload_2:
  16.219 +                case bc_iload_2:
  16.220 +                case bc_lload_2:
  16.221 +                case bc_fload_2:
  16.222 +                case bc_dload_2:
  16.223 +                    out.append("stack.push(arg2);");
  16.224 +                    break;
  16.225 +                case bc_aload_3:
  16.226 +                case bc_iload_3:
  16.227 +                case bc_lload_3:
  16.228 +                case bc_fload_3:
  16.229 +                case bc_dload_3:
  16.230 +                    out.append("stack.push(arg3);");
  16.231 +                    break;
  16.232 +                case bc_iload:
  16.233 +                case bc_lload:
  16.234 +                case bc_fload:
  16.235 +                case bc_dload:
  16.236 +                case bc_aload: {
  16.237 +                    final int indx = (byteCodes[++i] + 256) % 256;
  16.238 +                    out.append("stack.push(arg").append(indx + ");");
  16.239 +                    break;
  16.240 +                }
  16.241 +                case bc_astore_0:
  16.242 +                case bc_istore_0:
  16.243 +                case bc_lstore_0:
  16.244 +                case bc_fstore_0:
  16.245 +                case bc_dstore_0:
  16.246 +                    out.append("arg0 = stack.pop();");
  16.247 +                    break;
  16.248 +                case bc_astore_1:
  16.249 +                case bc_istore_1:
  16.250 +                case bc_lstore_1:
  16.251 +                case bc_fstore_1:
  16.252 +                case bc_dstore_1:
  16.253 +                    out.append("arg1 = stack.pop();");
  16.254 +                    break;
  16.255 +                case bc_astore_2:
  16.256 +                case bc_istore_2:
  16.257 +                case bc_lstore_2:
  16.258 +                case bc_fstore_2:
  16.259 +                case bc_dstore_2:
  16.260 +                    out.append("arg2 = stack.pop();");
  16.261 +                    break;
  16.262 +                case bc_astore_3:
  16.263 +                case bc_istore_3:
  16.264 +                case bc_lstore_3:
  16.265 +                case bc_fstore_3:
  16.266 +                case bc_dstore_3:
  16.267 +                    out.append("arg3 = stack.pop();");
  16.268 +                    break;
  16.269 +                case bc_iadd:
  16.270 +                case bc_ladd:
  16.271 +                case bc_fadd:
  16.272 +                case bc_dadd:
  16.273 +                    out.append("stack.push(stack.pop() + stack.pop());");
  16.274 +                    break;
  16.275 +                case bc_isub:
  16.276 +                case bc_lsub:
  16.277 +                case bc_fsub:
  16.278 +                case bc_dsub:
  16.279 +                    out.append("{ var tmp = stack.pop(); stack.push(stack.pop() - tmp); }");
  16.280 +                    break;
  16.281 +                case bc_imul:
  16.282 +                case bc_lmul:
  16.283 +                case bc_fmul:
  16.284 +                case bc_dmul:
  16.285 +                    out.append("stack.push(stack.pop() * stack.pop());");
  16.286 +                    break;
  16.287 +                case bc_idiv:
  16.288 +                case bc_ldiv:
  16.289 +                    out.append("{ var tmp = stack.pop(); stack.push(Math.floor(stack.pop() / tmp)); }");
  16.290 +                    break;
  16.291 +                case bc_fdiv:
  16.292 +                case bc_ddiv:
  16.293 +                    out.append("{ var tmp = stack.pop(); stack.push(stack.pop() / tmp); }");
  16.294 +                    break;
  16.295 +                case bc_iand:
  16.296 +                case bc_land:
  16.297 +                    out.append("stack.push(stack.pop() & stack.pop());");
  16.298 +                    break;
  16.299 +                case bc_ior:
  16.300 +                case bc_lor:
  16.301 +                    out.append("stack.push(stack.pop() | stack.pop());");
  16.302 +                    break;
  16.303 +                case bc_ixor:
  16.304 +                case bc_lxor:
  16.305 +                    out.append("stack.push(stack.pop() ^ stack.pop());");
  16.306 +                    break;
  16.307 +                case bc_iinc: {
  16.308 +                    final int varIndx = (byteCodes[++i] + 256) % 256;
  16.309 +                    final int incrBy = (byteCodes[++i] + 256) % 256;
  16.310 +                    if (incrBy == 1) {
  16.311 +                        out.append("arg" + varIndx).append("++;");
  16.312 +                    } else {
  16.313 +                        out.append("arg" + varIndx).append(" += " + incrBy).append(";");
  16.314 +                    }
  16.315 +                    break;
  16.316 +                }
  16.317 +                case bc_return:
  16.318 +                    out.append("return;");
  16.319 +                    break;
  16.320 +                case bc_ireturn:
  16.321 +                case bc_lreturn:
  16.322 +                case bc_freturn:
  16.323 +                case bc_dreturn:
  16.324 +                case bc_areturn:
  16.325 +                    out.append("return stack.pop();");
  16.326 +                    break;
  16.327 +                case bc_i2l:
  16.328 +                case bc_i2f:
  16.329 +                case bc_i2d:
  16.330 +                case bc_l2i:
  16.331 +                    // max int check?
  16.332 +                case bc_l2f:
  16.333 +                case bc_l2d:
  16.334 +                case bc_f2d:
  16.335 +                case bc_d2f:
  16.336 +                    out.append("/* number conversion */");
  16.337 +                    break;
  16.338 +                case bc_f2i:
  16.339 +                case bc_f2l:
  16.340 +                case bc_d2i:
  16.341 +                case bc_d2l:
  16.342 +                    out.append("stack.push(Math.floor(stack.pop()));");
  16.343 +                    break;
  16.344 +                case bc_i2b:
  16.345 +                case bc_i2c:
  16.346 +                case bc_i2s:
  16.347 +                    out.append("/* number conversion */");
  16.348 +                    break;
  16.349 +                case bc_iconst_0:
  16.350 +                case bc_dconst_0:
  16.351 +                case bc_lconst_0:
  16.352 +                case bc_fconst_0:
  16.353 +                    out.append("stack.push(0);");
  16.354 +                    break;
  16.355 +                case bc_iconst_1:
  16.356 +                case bc_lconst_1:
  16.357 +                case bc_fconst_1:
  16.358 +                case bc_dconst_1:
  16.359 +                    out.append("stack.push(1);");
  16.360 +                    break;
  16.361 +                case bc_iconst_2:
  16.362 +                case bc_fconst_2:
  16.363 +                    out.append("stack.push(2);");
  16.364 +                    break;
  16.365 +                case bc_iconst_3:
  16.366 +                    out.append("stack.push(3);");
  16.367 +                    break;
  16.368 +                case bc_iconst_4:
  16.369 +                    out.append("stack.push(4);");
  16.370 +                    break;
  16.371 +                case bc_iconst_5:
  16.372 +                    out.append("stack.push(5);");
  16.373 +                    break;
  16.374 +                case bc_ldc: {
  16.375 +                    int indx = byteCodes[++i];
  16.376 +                    CPEntry entry = jc.getConstantPool().get(indx);
  16.377 +                    String v = encodeConstant(entry);
  16.378 +                    out.append("stack.push(").append(v).append(");");
  16.379 +                    break;
  16.380 +                }
  16.381 +                case bc_ldc_w:
  16.382 +                case bc_ldc2_w: {
  16.383 +                    int indx = readIntArg(byteCodes, i);
  16.384 +                    CPEntry entry = jc.getConstantPool().get(indx);
  16.385 +                    i += 2;
  16.386 +                    String v = encodeConstant(entry);
  16.387 +                    out.append("stack.push(").append(v).append(");");
  16.388 +                    break;
  16.389 +                }
  16.390 +                case bc_lcmp:
  16.391 +                case bc_fcmpl:
  16.392 +                case bc_fcmpg:
  16.393 +                case bc_dcmpl:
  16.394 +                case bc_dcmpg: {
  16.395 +                    out.append("{ var delta = stack.pop() - stack.pop(); stack.push(delta < 0 ?-1 : (delta == 0 ? 0 : 1)); }");
  16.396 +                    break;
  16.397 +                }
  16.398 +                case bc_if_icmpeq: {
  16.399 +                    i = generateIf(byteCodes, i, "==");
  16.400 +                    break;
  16.401 +                }
  16.402 +                case bc_ifeq: {
  16.403 +                    int indx = i + readIntArg(byteCodes, i);
  16.404 +                    out.append("if (stack.pop() == 0) { gt = " + indx);
  16.405 +                    out.append("; continue; }");
  16.406 +                    i += 2;
  16.407 +                    break;
  16.408 +                }
  16.409 +                case bc_ifne: {
  16.410 +                    int indx = i + readIntArg(byteCodes, i);
  16.411 +                    out.append("if (stack.pop() != 0) { gt = " + indx);
  16.412 +                    out.append("; continue; }");
  16.413 +                    i += 2;
  16.414 +                    break;
  16.415 +                }
  16.416 +                case bc_iflt: {
  16.417 +                    int indx = i + readIntArg(byteCodes, i);
  16.418 +                    out.append("if (stack.pop() < 0) { gt = " + indx);
  16.419 +                    out.append("; continue; }");
  16.420 +                    i += 2;
  16.421 +                    break;
  16.422 +                }
  16.423 +                case bc_ifle: {
  16.424 +                    int indx = i + readIntArg(byteCodes, i);
  16.425 +                    out.append("if (stack.pop() <= 0) { gt = " + indx);
  16.426 +                    out.append("; continue; }");
  16.427 +                    i += 2;
  16.428 +                    break;
  16.429 +                }
  16.430 +                case bc_ifgt: {
  16.431 +                    int indx = i + readIntArg(byteCodes, i);
  16.432 +                    out.append("if (stack.pop() > 0) { gt = " + indx);
  16.433 +                    out.append("; continue; }");
  16.434 +                    i += 2;
  16.435 +                    break;
  16.436 +                }
  16.437 +                case bc_ifge: {
  16.438 +                    int indx = i + readIntArg(byteCodes, i);
  16.439 +                    out.append("if (stack.pop() >= 0) { gt = " + indx);
  16.440 +                    out.append("; continue; }");
  16.441 +                    i += 2;
  16.442 +                    break;
  16.443 +                }
  16.444 +                case bc_ifnonnull: {
  16.445 +                    int indx = i + readIntArg(byteCodes, i);
  16.446 +                    out.append("if (stack.pop()) { gt = " + indx);
  16.447 +                    out.append("; continue; }");
  16.448 +                    i += 2;
  16.449 +                    break;
  16.450 +                }
  16.451 +                case bc_ifnull: {
  16.452 +                    int indx = i + readIntArg(byteCodes, i);
  16.453 +                    out.append("if (!stack.pop()) { gt = " + indx);
  16.454 +                    out.append("; continue; }");
  16.455 +                    i += 2;
  16.456 +                    break;
  16.457 +                }
  16.458 +                case bc_if_icmpne:
  16.459 +                    i = generateIf(byteCodes, i, "!=");
  16.460 +                    break;
  16.461 +                case bc_if_icmplt:
  16.462 +                    i = generateIf(byteCodes, i, ">");
  16.463 +                    break;
  16.464 +                case bc_if_icmple:
  16.465 +                    i = generateIf(byteCodes, i, ">=");
  16.466 +                    break;
  16.467 +                case bc_if_icmpgt:
  16.468 +                    i = generateIf(byteCodes, i, "<");
  16.469 +                    break;
  16.470 +                case bc_if_icmpge:
  16.471 +                    i = generateIf(byteCodes, i, "<=");
  16.472 +                    break;
  16.473 +                case bc_goto: {
  16.474 +                    int indx = i + readIntArg(byteCodes, i);
  16.475 +                    out.append("gt = " + indx).append("; continue;");
  16.476 +                    i += 2;
  16.477 +                    break;
  16.478 +                }
  16.479 +                case bc_invokeinterface:
  16.480 +                case bc_invokevirtual:
  16.481 +                    i = invokeVirtualMethod(byteCodes, i);
  16.482 +                    break;
  16.483 +                case bc_invokespecial:
  16.484 +                    i = invokeStaticMethod(byteCodes, i, false);
  16.485 +                    break;
  16.486 +                case bc_invokestatic:
  16.487 +                    i = invokeStaticMethod(byteCodes, i, true);
  16.488 +                    break;
  16.489 +                case bc_new: {
  16.490 +                    int indx = readIntArg(byteCodes, i);
  16.491 +                    CPClassInfo ci = jc.getConstantPool().getClass(indx);
  16.492 +                    out.append("stack.push(");
  16.493 +                    out.append("new ").append(ci.getClassName().getInternalName().replace('/','_'));
  16.494 +                    out.append(");");
  16.495 +                    addReference(ci.getClassName().getInternalName());
  16.496 +                    i += 2;
  16.497 +                    break;
  16.498 +                }
  16.499 +                case bc_newarray: {
  16.500 +                    int type = byteCodes[i++];
  16.501 +                    out.append("stack.push(new Array(stack.pop()));");
  16.502 +                    break;
  16.503 +                }
  16.504 +                case bc_anewarray: {
  16.505 +                    i += 2; // skip type of array
  16.506 +                    out.append("stack.push(new Array(stack.pop()));");
  16.507 +                    break;
  16.508 +                }
  16.509 +                case bc_arraylength:
  16.510 +                    out.append("stack.push(stack.pop().length);");
  16.511 +                    break;
  16.512 +                case bc_iastore:
  16.513 +                case bc_lastore:
  16.514 +                case bc_fastore:
  16.515 +                case bc_dastore:
  16.516 +                case bc_aastore:
  16.517 +                case bc_bastore:
  16.518 +                case bc_castore:
  16.519 +                case bc_sastore: {
  16.520 +                    out.append("{ var value = stack.pop(); var indx = stack.pop(); stack.pop()[indx] = value; }");
  16.521 +                    break;
  16.522 +                }
  16.523 +                case bc_iaload:
  16.524 +                case bc_laload:
  16.525 +                case bc_faload:
  16.526 +                case bc_daload:
  16.527 +                case bc_aaload:
  16.528 +                case bc_baload:
  16.529 +                case bc_caload:
  16.530 +                case bc_saload: {
  16.531 +                    out.append("{ var indx = stack.pop(); stack.push(stack.pop()[indx]); }");
  16.532 +                    break;
  16.533 +                }
  16.534 +                case bc_dup:
  16.535 +                    out.append("stack.push(stack[stack.length - 1]);");
  16.536 +                    break;
  16.537 +                case bc_bipush:
  16.538 +                    out.append("stack.push(" + byteCodes[++i] + ");");
  16.539 +                    break;
  16.540 +                case bc_getfield: {
  16.541 +                    int indx = readIntArg(byteCodes, i);
  16.542 +                    CPFieldInfo fi = (CPFieldInfo) jc.getConstantPool().get(indx);
  16.543 +                    out.append("stack.push(stack.pop().").append(fi.getFieldName()).append(");");
  16.544 +                    i += 2;
  16.545 +                    break;
  16.546 +                }
  16.547 +                case bc_getstatic: {
  16.548 +                    int indx = readIntArg(byteCodes, i);
  16.549 +                    CPFieldInfo fi = (CPFieldInfo) jc.getConstantPool().get(indx);
  16.550 +                    final String in = fi.getClassName().getInternalName();
  16.551 +                    out.append("stack.push(").append(in.replace('/', '_'));
  16.552 +                    out.append('_').append(fi.getFieldName()).append(");");
  16.553 +                    i += 2;
  16.554 +                    addReference(in);
  16.555 +                    break;
  16.556 +                }
  16.557 +                case bc_putstatic: {
  16.558 +                    int indx = readIntArg(byteCodes, i);
  16.559 +                    CPFieldInfo fi = (CPFieldInfo) jc.getConstantPool().get(indx);
  16.560 +                    final String in = fi.getClassName().getInternalName();
  16.561 +                    out.append(in.replace('/', '_'));
  16.562 +                    out.append('_').append(fi.getFieldName()).append(" = stack.pop();");
  16.563 +                    i += 2;
  16.564 +                    addReference(in);
  16.565 +                    break;
  16.566 +                }
  16.567 +                case bc_putfield: {
  16.568 +                    int indx = readIntArg(byteCodes, i);
  16.569 +                    CPFieldInfo fi = (CPFieldInfo) jc.getConstantPool().get(indx);
  16.570 +                    out.append("{ var v = stack.pop(); stack.pop().")
  16.571 +                       .append(fi.getFieldName()).append(" = v; }");
  16.572 +                    i += 2;
  16.573 +                    break;
  16.574 +                }
  16.575 +                case bc_instanceof: {
  16.576 +                    int indx = readIntArg(byteCodes, i);
  16.577 +                    CPClassInfo ci = jc.getConstantPool().getClass(indx);
  16.578 +                    out.append("stack.push(stack.pop().$instOf_")
  16.579 +                       .append(ci.getClassName().getInternalName().replace('/', '_'))
  16.580 +                       .append(" ? 1 : 0);");
  16.581 +                    i += 2;
  16.582 +                }
  16.583 +                    
  16.584 +            }
  16.585 +            out.append(" /*");
  16.586 +            for (int j = prev; j <= i; j++) {
  16.587 +                out.append(" ");
  16.588 +                final int cc = (byteCodes[j] + 256) % 256;
  16.589 +                out.append(Integer.toString(cc));
  16.590 +            }
  16.591 +            out.append("*/\n");
  16.592 +        }
  16.593 +        out.append("  }\n");
  16.594 +    }
  16.595 +
  16.596 +    private int generateIf(byte[] byteCodes, int i, final String test) throws IOException {
  16.597 +        int indx = i + readIntArg(byteCodes, i);
  16.598 +        out.append("if (stack.pop() ").append(test).append(" stack.pop()) { gt = " + indx);
  16.599 +        out.append("; continue; }");
  16.600 +        return i + 2;
  16.601 +    }
  16.602 +
  16.603 +    private int readIntArg(byte[] byteCodes, int offsetInstruction) {
  16.604 +        final int indxHi = byteCodes[offsetInstruction + 1] << 8;
  16.605 +        final int indxLo = byteCodes[offsetInstruction + 2];
  16.606 +        return (indxHi & 0xffffff00) | (indxLo & 0xff);
  16.607 +    }
  16.608 +    
  16.609 +    private static int countArgs(String descriptor, boolean[] hasReturnType, StringBuilder sig) {
  16.610 +        int cnt = 0;
  16.611 +        int i = 0;
  16.612 +        Boolean count = null;
  16.613 +        int firstPos = sig.length();
  16.614 +        while (i < descriptor.length()) {
  16.615 +            char ch = descriptor.charAt(i++);
  16.616 +            switch (ch) {
  16.617 +                case '(':
  16.618 +                    count = true;
  16.619 +                    continue;
  16.620 +                case ')':
  16.621 +                    count = false;
  16.622 +                    continue;
  16.623 +                case 'B': 
  16.624 +                case 'C': 
  16.625 +                case 'D': 
  16.626 +                case 'F': 
  16.627 +                case 'I': 
  16.628 +                case 'J': 
  16.629 +                case 'S': 
  16.630 +                case 'Z': 
  16.631 +                    if (count) {
  16.632 +                        cnt++;
  16.633 +                        sig.append(ch);
  16.634 +                    } else {
  16.635 +                        hasReturnType[0] = true;
  16.636 +                        sig.insert(firstPos, ch);
  16.637 +                    }
  16.638 +                    continue;
  16.639 +                case 'V': 
  16.640 +                    assert !count;
  16.641 +                    hasReturnType[0] = false;
  16.642 +                    sig.insert(firstPos, 'V');
  16.643 +                    continue;
  16.644 +                case 'L':
  16.645 +                    int next = descriptor.indexOf(';', i);
  16.646 +                    if (count) {
  16.647 +                        cnt++;
  16.648 +                        sig.append(ch);
  16.649 +                        sig.append(descriptor.substring(i, next).replace('/', '_'));
  16.650 +                    } else {
  16.651 +                        sig.insert(firstPos, descriptor.substring(i, next).replace('/', '_'));
  16.652 +                        sig.insert(firstPos, ch);
  16.653 +                        hasReturnType[0] = true;
  16.654 +                    }
  16.655 +                    i = next + 1;
  16.656 +                    continue;
  16.657 +                case '[':
  16.658 +                    //arrays++;
  16.659 +                    continue;
  16.660 +                default:
  16.661 +                    break; // invalid character
  16.662 +            }
  16.663 +        }
  16.664 +        return cnt;
  16.665 +    }
  16.666 +
  16.667 +    private void generateStaticField(Variable v) throws IOException {
  16.668 +        out.append("\nvar ")
  16.669 +           .append(jc.getName().getInternalName().replace('/', '_'))
  16.670 +           .append('_').append(v.getName()).append(" = 0;");
  16.671 +    }
  16.672 +
  16.673 +    private String findMethodName(Method m) {
  16.674 +        StringBuilder tmp = new StringBuilder();
  16.675 +        if ("<init>".equals(m.getName())) { // NOI18N
  16.676 +            tmp.append("consV"); // NOI18N
  16.677 +        } else if ("<clinit>".equals(m.getName())) { // NOI18N
  16.678 +            tmp.append("classV"); // NOI18N
  16.679 +        } else {
  16.680 +            tmp.append(m.getName());
  16.681 +            outType(m.getReturnType(), tmp);
  16.682 +        } 
  16.683 +        List<Parameter> args = m.getParameters();
  16.684 +        for (Parameter t : args) {
  16.685 +            outType(t.getDescriptor(), tmp);
  16.686 +        }
  16.687 +        return tmp.toString();
  16.688 +    }
  16.689 +
  16.690 +    private String findMethodName(CPMethodInfo mi, int[] cnt, boolean[] hasReturn) {
  16.691 +        StringBuilder name = new StringBuilder();
  16.692 +        if ("<init>".equals(mi.getName())) { // NOI18N
  16.693 +            name.append("cons"); // NOI18N
  16.694 +        } else {
  16.695 +            name.append(mi.getName());
  16.696 +        }
  16.697 +        cnt[0] = countArgs(mi.getDescriptor(), hasReturn, name);
  16.698 +        return name.toString();
  16.699 +    }
  16.700 +
  16.701 +    private int invokeStaticMethod(byte[] byteCodes, int i, boolean isStatic)
  16.702 +    throws IOException {
  16.703 +        int methodIndex = readIntArg(byteCodes, i);
  16.704 +        CPMethodInfo mi = (CPMethodInfo) jc.getConstantPool().get(methodIndex);
  16.705 +        boolean[] hasReturn = { false };
  16.706 +        int[] cnt = { 0 };
  16.707 +        String mn = findMethodName(mi, cnt, hasReturn);
  16.708 +        out.append("{ ");
  16.709 +        for (int j = cnt[0] - 1; j >= 0; j--) {
  16.710 +            out.append("var v" + j).append(" = stack.pop(); ");
  16.711 +        }
  16.712 +        
  16.713 +        if (hasReturn[0]) {
  16.714 +            out.append("stack.push(");
  16.715 +        }
  16.716 +        final String in = mi.getClassName().getInternalName();
  16.717 +        out.append(in.replace('/', '_'));
  16.718 +        out.append('_');
  16.719 +        out.append(mn);
  16.720 +        out.append('(');
  16.721 +        String sep = "";
  16.722 +        if (!isStatic) {
  16.723 +            out.append("stack.pop()");
  16.724 +            sep = ", ";
  16.725 +        }
  16.726 +        for (int j = 0; j < cnt[0]; j++) {
  16.727 +            out.append(sep);
  16.728 +            out.append("v" + j);
  16.729 +            sep = ", ";
  16.730 +        }
  16.731 +        out.append(")");
  16.732 +        if (hasReturn[0]) {
  16.733 +            out.append(")");
  16.734 +        }
  16.735 +        out.append("; }");
  16.736 +        i += 2;
  16.737 +        addReference(in);
  16.738 +        return i;
  16.739 +    }
  16.740 +    private int invokeVirtualMethod(byte[] byteCodes, int i)
  16.741 +    throws IOException {
  16.742 +        int methodIndex = readIntArg(byteCodes, i);
  16.743 +        CPMethodInfo mi = (CPMethodInfo) jc.getConstantPool().get(methodIndex);
  16.744 +        boolean[] hasReturn = { false };
  16.745 +        int[] cnt = { 0 };
  16.746 +        String mn = findMethodName(mi, cnt, hasReturn);
  16.747 +        out.append("{ ");
  16.748 +        for (int j = cnt[0] - 1; j >= 0; j--) {
  16.749 +            out.append("var v" + j).append(" = stack.pop(); ");
  16.750 +        }
  16.751 +        out.append("var self = stack.pop(); ");
  16.752 +        if (hasReturn[0]) {
  16.753 +            out.append("stack.push(");
  16.754 +        }
  16.755 +        out.append("self.");
  16.756 +        out.append(mn);
  16.757 +        out.append('(');
  16.758 +        out.append("self");
  16.759 +        for (int j = 0; j < cnt[0]; j++) {
  16.760 +            out.append(", ");
  16.761 +            out.append("v" + j);
  16.762 +        }
  16.763 +        out.append(")");
  16.764 +        if (hasReturn[0]) {
  16.765 +            out.append(")");
  16.766 +        }
  16.767 +        out.append("; }");
  16.768 +        i += 2;
  16.769 +        return i;
  16.770 +    }
  16.771 +    
  16.772 +    private void addReference(String cn) {
  16.773 +        if (references != null) {
  16.774 +            references.add(cn);
  16.775 +        }
  16.776 +    }
  16.777 +
  16.778 +    private void outType(final String d, StringBuilder out) {
  16.779 +        if (d.charAt(0) == 'L') {
  16.780 +            assert d.charAt(d.length() - 1) == ';';
  16.781 +            out.append(d.replace('/', '_').substring(0, d.length() - 1));
  16.782 +        } else {
  16.783 +            out.append(d);
  16.784 +        }
  16.785 +    }
  16.786 +
  16.787 +    private String encodeConstant(CPEntry entry) {
  16.788 +        final String v;
  16.789 +        if (entry instanceof CPStringInfo) {
  16.790 +            v = "\"" + entry.getValue().toString().replace("\"", "\\\"") + "\"";
  16.791 +        } else {
  16.792 +            v = entry.getValue().toString();
  16.793 +        }
  16.794 +        return v;
  16.795 +    }
  16.796 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Array.java	Mon Sep 24 11:07:38 2012 +0200
    17.3 @@ -0,0 +1,76 @@
    17.4 +/*
    17.5 +Java 4 Browser Bytecode Translator
    17.6 +Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    17.7 +
    17.8 +This program is free software: you can redistribute it and/or modify
    17.9 +it under the terms of the GNU General Public License as published by
   17.10 +the Free Software Foundation, version 2 of the License.
   17.11 +
   17.12 +This program is distributed in the hope that it will be useful,
   17.13 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.14 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.15 +GNU General Public License for more details.
   17.16 +
   17.17 +You should have received a copy of the GNU General Public License
   17.18 +along with this program. Look for COPYING file in the top folder.
   17.19 +If not, see http://opensource.org/licenses/GPL-2.0.
   17.20 +*/
   17.21 +package org.apidesign.vm4brwsr;
   17.22 +
   17.23 +/**
   17.24 + *
   17.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   17.26 + */
   17.27 +public class Array {
   17.28 +    byte[] bytes = { 1 };
   17.29 +    short[] shorts = { 2, 3 };
   17.30 +    int[] ints = { 4, 5, 6 };
   17.31 +    float[] floats = { 7, 8, 9, 10 };
   17.32 +    double[][] doubles = { {11}, {12}, {13}, {14}, {15} };
   17.33 +    char[] chars = { 'a', 'b' };
   17.34 +    
   17.35 +    private Array() {
   17.36 +    }
   17.37 +    
   17.38 +    byte bytes() {
   17.39 +        return bytes[0];
   17.40 +    }
   17.41 +    short shorts() {
   17.42 +        return shorts[1];
   17.43 +    }
   17.44 +    
   17.45 +    int ints() {
   17.46 +        return ints[2];
   17.47 +    }
   17.48 +    
   17.49 +    float floats() {
   17.50 +        return floats[3];
   17.51 +    }
   17.52 +    
   17.53 +    double doubles() {
   17.54 +        return doubles[4][0];
   17.55 +    }
   17.56 +    
   17.57 +    private static final Array[] ARR = { new Array(), new Array(), new Array() };
   17.58 +    
   17.59 +    public static double sum() {
   17.60 +        double sum = 0.0;
   17.61 +        for (int i = 0; i < ARR.length; i++) {
   17.62 +            sum += ARR[i].bytes();
   17.63 +            sum += ARR[i].shorts();
   17.64 +            sum += ARR[i].ints();
   17.65 +            sum += ARR[i].floats();
   17.66 +            sum += ARR[i].doubles();
   17.67 +        }
   17.68 +        return sum;
   17.69 +    }
   17.70 +    public static int simple() {
   17.71 +        int[] arr = { 0, 1, 2, 3, 4, 5 };
   17.72 +        
   17.73 +        int sum = 0;
   17.74 +        for (int i = 0; i < arr.length; i++) {
   17.75 +            sum += arr[i];
   17.76 +        }
   17.77 +        return sum;
   17.78 +    }
   17.79 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/ArrayTest.java	Mon Sep 24 11:07:38 2012 +0200
    18.3 @@ -0,0 +1,63 @@
    18.4 +/*
    18.5 +Java 4 Browser Bytecode Translator
    18.6 +Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    18.7 +
    18.8 +This program is free software: you can redistribute it and/or modify
    18.9 +it under the terms of the GNU General Public License as published by
   18.10 +the Free Software Foundation, version 2 of the License.
   18.11 +
   18.12 +This program is distributed in the hope that it will be useful,
   18.13 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.14 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.15 +GNU General Public License for more details.
   18.16 +
   18.17 +You should have received a copy of the GNU General Public License
   18.18 +along with this program. Look for COPYING file in the top folder.
   18.19 +If not, see http://opensource.org/licenses/GPL-2.0.
   18.20 +*/
   18.21 +package org.apidesign.vm4brwsr;
   18.22 +
   18.23 +import javax.script.Invocable;
   18.24 +import javax.script.ScriptException;
   18.25 +import org.testng.annotations.Test;
   18.26 +import static org.testng.Assert.*;
   18.27 +
   18.28 +/**
   18.29 + *
   18.30 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   18.31 + */
   18.32 +public class ArrayTest {
   18.33 +    @Test public void verifySimpleIntOperation() throws Exception {
   18.34 +        assertExec("CheckTheSum", "org_apidesign_vm4brwsr_Array_simpleI", 
   18.35 +            Double.valueOf(15)
   18.36 +        );
   18.37 +    }
   18.38 +    @Test public void verifyOperationsOnArrays() throws Exception {
   18.39 +        assertExec("The sum is 105", "org_apidesign_vm4brwsr_Array_sumD", 
   18.40 +            Double.valueOf(105)
   18.41 +        );
   18.42 +    }
   18.43 +    
   18.44 +    private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception {
   18.45 +        StringBuilder sb = new StringBuilder();
   18.46 +        Invocable i = StaticMethodTest.compileClass(sb, 
   18.47 +            "org/apidesign/vm4brwsr/Array"
   18.48 +        );
   18.49 +        
   18.50 +        Object ret = null;
   18.51 +        try {
   18.52 +            ret = i.invokeFunction(methodName, args);
   18.53 +        } catch (ScriptException ex) {
   18.54 +            fail("Execution failed in " + sb, ex);
   18.55 +        } catch (NoSuchMethodException ex) {
   18.56 +            fail("Cannot find method in " + sb, ex);
   18.57 +        }
   18.58 +        if (ret == null && expRes == null) {
   18.59 +            return;
   18.60 +        }
   18.61 +        if (expRes.equals(ret)) {
   18.62 +            return;
   18.63 +        }
   18.64 +        assertEquals(ret, expRes, msg + "was: " + ret + "\n" + sb);
   18.65 +    }
   18.66 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/GetByte.java	Mon Sep 24 11:07:38 2012 +0200
    19.3 @@ -0,0 +1,9 @@
    19.4 +/*
    19.5 + * To change this template, choose Tools | Templates
    19.6 + * and open the template in the editor.
    19.7 + */
    19.8 +package org.apidesign.vm4brwsr;
    19.9 +
   19.10 +public interface GetByte {
   19.11 +    public byte getByte();
   19.12 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/Instance.java	Mon Sep 24 11:07:38 2012 +0200
    20.3 @@ -0,0 +1,69 @@
    20.4 +/*
    20.5 + * To change this template, choose Tools | Templates
    20.6 + * and open the template in the editor.
    20.7 + */
    20.8 +package org.apidesign.vm4brwsr;
    20.9 +
   20.10 +/**
   20.11 + *
   20.12 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   20.13 + */
   20.14 +public class Instance {
   20.15 +    private int i;
   20.16 +    protected short s;
   20.17 +    public double d;
   20.18 +    private float f;
   20.19 +    protected byte b = (byte)31;
   20.20 +    
   20.21 +    private Instance() {
   20.22 +    }
   20.23 +
   20.24 +    public Instance(int i, double d) {
   20.25 +        this.i = i;
   20.26 +        this.d = d;
   20.27 +    }
   20.28 +    public byte getByte() {
   20.29 +        return b;
   20.30 +    }
   20.31 +    
   20.32 +    public void setByte(byte b) {
   20.33 +        this.b = b;
   20.34 +    }
   20.35 +    public static double defaultDblValue() {
   20.36 +        Instance create = new Instance();
   20.37 +        return create.d;
   20.38 +    }
   20.39 +    
   20.40 +    public static byte assignedByteValue() {
   20.41 +        return new Instance().b;
   20.42 +    }
   20.43 +    public static double magicOne() {
   20.44 +        Instance i = new Instance(10, 3.3d);
   20.45 +        i.b = (byte)0x09;
   20.46 +        return (i.i - i.b) * i.d;
   20.47 +    }
   20.48 +    public static int virtualBytes() {
   20.49 +        Instance i = new InstanceSub(7, 2.2d);
   20.50 +        i.setByte((byte)0x0a);
   20.51 +        Instance i2 = new Instance(3, 333.0d);
   20.52 +        i2.setByte((byte)44);
   20.53 +        return i.getByte() + i2.getByte();
   20.54 +    }
   20.55 +    public static float interfaceBytes() {
   20.56 +        GetByte i = new InstanceSub(7, 2.2d);
   20.57 +        return i.getByte();
   20.58 +    }
   20.59 +    public static boolean instanceOf(boolean sub) {
   20.60 +        Instance i = createInstance(sub);
   20.61 +        return isInstanceSubOf(i);
   20.62 +    }
   20.63 +    private static boolean isInstanceSubOf(Instance instance) {
   20.64 +        return instance instanceof InstanceSub;
   20.65 +    }
   20.66 +    private static Instance createInstance(boolean sub) {
   20.67 +        return sub ? new InstanceSub(3, 0) : new Instance();
   20.68 +    }
   20.69 +    private static boolean isNull() {
   20.70 +        return createInstance(true) == null;
   20.71 +    }
   20.72 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceSub.java	Mon Sep 24 11:07:38 2012 +0200
    21.3 @@ -0,0 +1,20 @@
    21.4 +/*
    21.5 + * To change this template, choose Tools | Templates
    21.6 + * and open the template in the editor.
    21.7 + */
    21.8 +package org.apidesign.vm4brwsr;
    21.9 +
   21.10 +/**
   21.11 + *
   21.12 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   21.13 + */
   21.14 +public class InstanceSub extends Instance implements GetByte {
   21.15 +    public InstanceSub(int i, double d) {
   21.16 +        super(i, d);
   21.17 +    }
   21.18 +    
   21.19 +    @Override
   21.20 +    public void setByte(byte b) {
   21.21 +        super.setByte((byte) (b + 1));
   21.22 +    }
   21.23 +}
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/InstanceTest.java	Mon Sep 24 11:07:38 2012 +0200
    22.3 @@ -0,0 +1,101 @@
    22.4 +/*
    22.5 + * To change this template, choose Tools | Templates
    22.6 + * and open the template in the editor.
    22.7 + */
    22.8 +package org.apidesign.vm4brwsr;
    22.9 +
   22.10 +import javax.script.Invocable;
   22.11 +import javax.script.ScriptException;
   22.12 +import org.testng.annotations.Test;
   22.13 +import static org.testng.Assert.*;
   22.14 +
   22.15 +/**
   22.16 + *
   22.17 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   22.18 + */
   22.19 +public class InstanceTest {
   22.20 +    @Test public void verifyDefaultDoubleValue() throws Exception {
   22.21 +        assertExec(
   22.22 +            "Will be zero",
   22.23 +            "org_apidesign_vm4brwsr_Instance_defaultDblValueD",
   22.24 +            Double.valueOf(0)
   22.25 +        );
   22.26 +    }
   22.27 +    @Test public void verifyAssignedByteValue() throws Exception {
   22.28 +        assertExec(
   22.29 +            "Will one thirty one",
   22.30 +            "org_apidesign_vm4brwsr_Instance_assignedByteValueB",
   22.31 +            Double.valueOf(31)
   22.32 +        );
   22.33 +    }
   22.34 +    @Test public void verifyMagicOne() throws Exception {
   22.35 +        assertExec(
   22.36 +            "Should be three and something",
   22.37 +            "org_apidesign_vm4brwsr_Instance_magicOneD",
   22.38 +            Double.valueOf(3.3)
   22.39 +        );
   22.40 +    }
   22.41 +    @Test public void verifyInstanceMethods() throws Exception {
   22.42 +        assertExec(
   22.43 +            "Should be eleven as we invoke overwritten method, plus 44",
   22.44 +            "org_apidesign_vm4brwsr_Instance_virtualBytesI",
   22.45 +            Double.valueOf(55)
   22.46 +        );
   22.47 +    }
   22.48 +    @Test public void verifyInterfaceMethods() throws Exception {
   22.49 +        assertExec(
   22.50 +            "Retruns default value",
   22.51 +            "org_apidesign_vm4brwsr_Instance_interfaceBytesF",
   22.52 +            Double.valueOf(31)
   22.53 +        );
   22.54 +    }
   22.55 +
   22.56 +    @Test public void isNull() throws Exception {
   22.57 +        assertExec(
   22.58 +            "Yes, we are instance",
   22.59 +            "org_apidesign_vm4brwsr_Instance_isNullZ",
   22.60 +            Double.valueOf(0.0)
   22.61 +        );
   22.62 +    }
   22.63 +
   22.64 +    @Test public void isInstanceOf() throws Exception {
   22.65 +        assertExec(
   22.66 +            "Yes, we are instance",
   22.67 +            "org_apidesign_vm4brwsr_Instance_instanceOfZZ",
   22.68 +            Double.valueOf(1.0), true
   22.69 +        );
   22.70 +    }
   22.71 +
   22.72 +    @Test public void notInstanceOf() throws Exception {
   22.73 +        assertExec(
   22.74 +            "No, we are not an instance",
   22.75 +            "org_apidesign_vm4brwsr_Instance_instanceOfZZ",
   22.76 +            Double.valueOf(0.0), false
   22.77 +        );
   22.78 +    }
   22.79 +    
   22.80 +    private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception {
   22.81 +        StringBuilder sb = new StringBuilder();
   22.82 +        Invocable i = StaticMethodTest.compileClass(sb, 
   22.83 +            "org/apidesign/vm4brwsr/Instance"
   22.84 +        );
   22.85 +        
   22.86 +        Object ret = null;
   22.87 +        try {
   22.88 +            ret = i.invokeFunction(methodName, args);
   22.89 +        } catch (ScriptException ex) {
   22.90 +            fail("Execution failed in " + sb, ex);
   22.91 +        } catch (NoSuchMethodException ex) {
   22.92 +            fail("Cannot find method in " + sb, ex);
   22.93 +        }
   22.94 +        if (ret == null && expRes == null) {
   22.95 +            return;
   22.96 +        }
   22.97 +        if (expRes.equals(ret)) {
   22.98 +            return;
   22.99 +        }
  22.100 +        assertEquals(ret, expRes, msg + "was: " + ret + "\n" + sb);
  22.101 +        
  22.102 +    }
  22.103 +    
  22.104 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java	Mon Sep 24 11:07:38 2012 +0200
    23.3 @@ -0,0 +1,68 @@
    23.4 +/*
    23.5 +Java 4 Browser Bytecode Translator
    23.6 +Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    23.7 +
    23.8 +This program is free software: you can redistribute it and/or modify
    23.9 +it under the terms of the GNU General Public License as published by
   23.10 +the Free Software Foundation, version 2 of the License.
   23.11 +
   23.12 +This program is distributed in the hope that it will be useful,
   23.13 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.14 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.15 +GNU General Public License for more details.
   23.16 +
   23.17 +You should have received a copy of the GNU General Public License
   23.18 +along with this program. Look for COPYING file in the top folder.
   23.19 +If not, see http://opensource.org/licenses/GPL-2.0.
   23.20 +*/
   23.21 +package org.apidesign.vm4brwsr;
   23.22 +
   23.23 +/**
   23.24 + *
   23.25 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   23.26 + */
   23.27 +public class StaticMethod {
   23.28 +    private static int cnt;
   23.29 +    
   23.30 +    public static int sum(int x, int y) {
   23.31 +        return x + y;
   23.32 +    }
   23.33 +    public static float power(float x) {
   23.34 +        return x * x;
   23.35 +    }
   23.36 +    public static double minus(double x, long y) {
   23.37 +        return x - y;
   23.38 +    }
   23.39 +    public static int div(byte c, double d) {
   23.40 +        return (int)(d / c);
   23.41 +    }
   23.42 +    public static int mix(int a, long b, byte c, double d) {
   23.43 +        return (int)((b / a + c) * d);
   23.44 +    }
   23.45 +    public static long xor(int a, long b) {
   23.46 +        return a ^ b;
   23.47 +    }
   23.48 +    public static long orOrAnd(boolean doOr, int a, int b) {
   23.49 +        return doOr ? a | b : a & b;
   23.50 +    }
   23.51 +    public static long factRec(int n) {
   23.52 +        if (n <= 1) {
   23.53 +            return 1;
   23.54 +        } else {
   23.55 +            return n * factRec(n - 1);
   23.56 +        }
   23.57 +    }
   23.58 +    public static long factIter(int n) {
   23.59 +        long res = 1;
   23.60 +        for (int i = 2; i <= n; i++) {
   23.61 +            res *= i;
   23.62 +        }
   23.63 +        return res;
   23.64 +    }
   23.65 +    public static int inc4() {
   23.66 +        cnt++;
   23.67 +        cnt+=2;
   23.68 +        cnt++;
   23.69 +        return cnt;
   23.70 +    }
   23.71 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java	Mon Sep 24 11:07:38 2012 +0200
    24.3 @@ -0,0 +1,202 @@
    24.4 +/*
    24.5 +Java 4 Browser Bytecode Translator
    24.6 +Copyright (C) 2012-2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    24.7 +
    24.8 +This program is free software: you can redistribute it and/or modify
    24.9 +it under the terms of the GNU General Public License as published by
   24.10 +the Free Software Foundation, version 2 of the License.
   24.11 +
   24.12 +This program is distributed in the hope that it will be useful,
   24.13 +but WITHOUT ANY WARRANTY; without even the implied warranty of
   24.14 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   24.15 +GNU General Public License for more details.
   24.16 +
   24.17 +You should have received a copy of the GNU General Public License
   24.18 +along with this program. Look for COPYING file in the top folder.
   24.19 +If not, see http://opensource.org/licenses/GPL-2.0.
   24.20 +*/
   24.21 +package org.apidesign.vm4brwsr;
   24.22 +
   24.23 +import org.apidesign.vm4brwsr.ByteCodeToJavaScript;
   24.24 +import java.io.IOException;
   24.25 +import java.io.InputStream;
   24.26 +import java.util.Arrays;
   24.27 +import java.util.HashSet;
   24.28 +import java.util.Iterator;
   24.29 +import java.util.LinkedList;
   24.30 +import java.util.Set;
   24.31 +import java.util.TreeSet;
   24.32 +import javax.script.Invocable;
   24.33 +import javax.script.ScriptEngine;
   24.34 +import javax.script.ScriptEngineManager;
   24.35 +import javax.script.ScriptException;
   24.36 +import static org.testng.Assert.*;
   24.37 +import org.testng.annotations.Test;
   24.38 +
   24.39 +/** Checks the basic behavior of the translator.
   24.40 + *
   24.41 + * @author Jaroslav Tulach <jtulach@netbeans.org>
   24.42 + */
   24.43 +public class StaticMethodTest {
   24.44 +    @Test public void threePlusFour() throws Exception {
   24.45 +        assertExec(
   24.46 +            "Should be seven", 
   24.47 +            "org_apidesign_vm4brwsr_StaticMethod_sumIII", 
   24.48 +            Double.valueOf(7), 
   24.49 +            3, 4
   24.50 +        );
   24.51 +    }
   24.52 +
   24.53 +    @Test public void powerOfThree() throws Exception {
   24.54 +        assertExec(
   24.55 +            "Should be nine", 
   24.56 +            "org_apidesign_vm4brwsr_StaticMethod_powerFF", 
   24.57 +            Double.valueOf(9),
   24.58 +            3.0f
   24.59 +        );
   24.60 +    }
   24.61 +
   24.62 +    @Test public void doubleWithoutLong() throws Exception {
   24.63 +        assertExec(
   24.64 +            "Should be two",
   24.65 +            "org_apidesign_vm4brwsr_StaticMethod_minusDDJ", 
   24.66 +            Double.valueOf(2),
   24.67 +            3.0d, 1l
   24.68 +        );
   24.69 +    }
   24.70 +
   24.71 +    @Test public void divAndRound() throws Exception {
   24.72 +        assertExec(
   24.73 +            "Should be rounded to one",
   24.74 +            "org_apidesign_vm4brwsr_StaticMethod_divIBD", 
   24.75 +            Double.valueOf(1),
   24.76 +            3, 3.75
   24.77 +        );
   24.78 +    }
   24.79 +    @Test public void mixedMethodFourParams() throws Exception {
   24.80 +        assertExec(
   24.81 +            "Should be two",
   24.82 +            "org_apidesign_vm4brwsr_StaticMethod_mixIIJBD", 
   24.83 +            Double.valueOf(20),
   24.84 +            2, 10l, 5, 2.0
   24.85 +        );
   24.86 +    }
   24.87 +    @Test public void factRec() throws Exception {
   24.88 +        assertExec(
   24.89 +            "Factorial of 5 is 120",
   24.90 +            "org_apidesign_vm4brwsr_StaticMethod_factRecJI", 
   24.91 +            Double.valueOf(120),
   24.92 +            5
   24.93 +        );
   24.94 +    }
   24.95 +    @Test public void factIter() throws Exception {
   24.96 +        assertExec(
   24.97 +            "Factorial of 5 is 120",
   24.98 +            "org_apidesign_vm4brwsr_StaticMethod_factIterJI", 
   24.99 +            Double.valueOf(120),
  24.100 +            5
  24.101 +        );
  24.102 +    }
  24.103 +    
  24.104 +    @Test public void xor() throws Exception {
  24.105 +        assertExec(
  24.106 +            "Xor is 4",
  24.107 +            "org_apidesign_vm4brwsr_StaticMethod_xorJIJ",
  24.108 +            Double.valueOf(4),
  24.109 +            7,
  24.110 +            3
  24.111 +        );
  24.112 +    }
  24.113 +    
  24.114 +    @Test public void or() throws Exception {
  24.115 +        assertExec(
  24.116 +            "Or will be 7",
  24.117 +            "org_apidesign_vm4brwsr_StaticMethod_orOrAndJZII",
  24.118 +            Double.valueOf(7),
  24.119 +            true,
  24.120 +            4,
  24.121 +            3
  24.122 +        );
  24.123 +    }
  24.124 +    @Test public void and() throws Exception {
  24.125 +        assertExec(
  24.126 +            "And will be 3",
  24.127 +            "org_apidesign_vm4brwsr_StaticMethod_orOrAndJZII",
  24.128 +            Double.valueOf(3),
  24.129 +            false,
  24.130 +            7,
  24.131 +            3
  24.132 +        );
  24.133 +    }
  24.134 +    @Test public void inc4() throws Exception {
  24.135 +        assertExec(
  24.136 +            "It will be 4",
  24.137 +            "org_apidesign_vm4brwsr_StaticMethod_inc4I",
  24.138 +            Double.valueOf(4)
  24.139 +        );
  24.140 +    }
  24.141 +    
  24.142 +    private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception {
  24.143 +        StringBuilder sb = new StringBuilder();
  24.144 +        Invocable i = compileClass(sb, "org/apidesign/vm4brwsr/StaticMethod");
  24.145 +        
  24.146 +        Object ret = null;
  24.147 +        try {
  24.148 +            ret = i.invokeFunction(methodName, args);
  24.149 +        } catch (ScriptException ex) {
  24.150 +            fail("Execution failed in " + sb, ex);
  24.151 +        } catch (NoSuchMethodException ex) {
  24.152 +            fail("Cannot find method in " + sb, ex);
  24.153 +        }
  24.154 +        if (ret == null && expRes == null) {
  24.155 +            return;
  24.156 +        }
  24.157 +        if (expRes.equals(ret)) {
  24.158 +            return;
  24.159 +        }
  24.160 +        assertEquals(ret, expRes, msg + "was: " + ret + "\n" + sb);
  24.161 +        
  24.162 +    }
  24.163 +
  24.164 +    static Invocable compileClass(StringBuilder sb, String... names) throws ScriptException, IOException {
  24.165 +        if (sb == null) {
  24.166 +            sb = new StringBuilder();
  24.167 +        }
  24.168 +        Set<String> processed = new HashSet<String>();
  24.169 +
  24.170 +        LinkedList<String> toProcess = new LinkedList<String>(Arrays.asList(names));
  24.171 +        for (;;) {
  24.172 +            toProcess.removeAll(processed);
  24.173 +            if (toProcess.isEmpty()) {
  24.174 +                break;
  24.175 +            }
  24.176 +            String name = toProcess.getFirst();
  24.177 +            processed.add(name);
  24.178 +            if (name.startsWith("java/") && !name.equals("java/lang/Object")) {
  24.179 +                continue;
  24.180 +            }
  24.181 +            InputStream is = StaticMethodTest.class.getClassLoader().getResourceAsStream(name + ".class");
  24.182 +            assertNotNull(is, "Class file found");
  24.183 +            try {
  24.184 +                ByteCodeToJavaScript.compile(is, sb, toProcess);
  24.185 +            } catch (RuntimeException ex) {
  24.186 +                int lastBlock = sb.lastIndexOf("{");
  24.187 +                throw new IllegalStateException(
  24.188 +                    "Error while compiling " + name + "\n" + 
  24.189 +                    sb.substring(0, sb.length()), 
  24.190 +                    ex
  24.191 +                );
  24.192 +            }
  24.193 +        }
  24.194 +        ScriptEngineManager sem = new ScriptEngineManager();
  24.195 +        ScriptEngine js = sem.getEngineByExtension("js");
  24.196 +        try {
  24.197 +            Object res = js.eval(sb.toString());
  24.198 +            assertTrue(js instanceof Invocable, "It is invocable object: " + res);
  24.199 +            return (Invocable)js;
  24.200 +        } catch (ScriptException ex) {
  24.201 +            fail("Could not compile:\n" + sb, ex);
  24.202 +            return null;
  24.203 +        }
  24.204 +    }
  24.205 +}