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 +}