Support for subtraction. Double occupies two slots. static import of byte codes.
1.1 --- a/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Mon Aug 27 05:17:08 2012 +0200
1.2 +++ b/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Mon Aug 27 05:47:44 2012 +0200
1.3 @@ -20,7 +20,7 @@
1.4 import java.io.IOException;
1.5 import java.io.InputStream;
1.6 import java.util.List;
1.7 -import org.netbeans.modules.classfile.ByteCodes;
1.8 +import static org.netbeans.modules.classfile.ByteCodes.*;
1.9 import org.netbeans.modules.classfile.ClassFile;
1.10 import org.netbeans.modules.classfile.Code;
1.11 import org.netbeans.modules.classfile.Method;
1.12 @@ -67,10 +67,16 @@
1.13 }
1.14 out.append('(');
1.15 String space = "";
1.16 - for (int i = 0; i < args.size(); i++) {
1.17 + for (int index = 0, i = 0; i < args.size(); i++) {
1.18 out.append(space);
1.19 - out.append("arg").append(String.valueOf(i));
1.20 + out.append("arg").append(String.valueOf(index));
1.21 space = ",";
1.22 + final String desc = args.get(i).getDescriptor();
1.23 + if ("D".equals(desc)) {
1.24 + index += 2;
1.25 + } else {
1.26 + index++;
1.27 + }
1.28 }
1.29 out.append(") {").append("\n var ");
1.30 final Code code = m.getCode();
1.31 @@ -94,38 +100,68 @@
1.32 out.append(" ");
1.33 final int c = (byteCodes[i] + 256) % 256;
1.34 switch (c) {
1.35 - case ByteCodes.bc_aload_0:
1.36 - case ByteCodes.bc_iload_0:
1.37 - case ByteCodes.bc_lload_0:
1.38 - case ByteCodes.bc_fload_0:
1.39 - case ByteCodes.bc_dload_0:
1.40 + case bc_aload_0:
1.41 + case bc_iload_0:
1.42 + case bc_lload_0:
1.43 + case bc_fload_0:
1.44 + case bc_dload_0:
1.45 out.append("stack.push(arg0);");
1.46 break;
1.47 - case ByteCodes.bc_aload_1:
1.48 - case ByteCodes.bc_iload_1:
1.49 - case ByteCodes.bc_lload_1:
1.50 - case ByteCodes.bc_fload_1:
1.51 - case ByteCodes.bc_dload_1:
1.52 + case bc_aload_1:
1.53 + case bc_iload_1:
1.54 + case bc_lload_1:
1.55 + case bc_fload_1:
1.56 + case bc_dload_1:
1.57 out.append("stack.push(arg1);");
1.58 break;
1.59 - case ByteCodes.bc_iadd:
1.60 - case ByteCodes.bc_ladd:
1.61 - case ByteCodes.bc_fadd:
1.62 - case ByteCodes.bc_dadd:
1.63 + case bc_aload_2:
1.64 + case bc_iload_2:
1.65 + case bc_lload_2:
1.66 + case bc_fload_2:
1.67 + case bc_dload_2:
1.68 + out.append("stack.push(arg2);");
1.69 + break;
1.70 + case bc_iadd:
1.71 + case bc_ladd:
1.72 + case bc_fadd:
1.73 + case bc_dadd:
1.74 out.append("stack.push(stack.pop() + stack.pop());");
1.75 break;
1.76 - case ByteCodes.bc_imul:
1.77 - case ByteCodes.bc_lmul:
1.78 - case ByteCodes.bc_fmul:
1.79 - case ByteCodes.bc_dmul:
1.80 + case bc_isub:
1.81 + case bc_lsub:
1.82 + case bc_fsub:
1.83 + case bc_dsub:
1.84 + out.append("stack.push(- stack.pop() + stack.pop());");
1.85 + break;
1.86 + case bc_imul:
1.87 + case bc_lmul:
1.88 + case bc_fmul:
1.89 + case bc_dmul:
1.90 out.append("stack.push(stack.pop() * stack.pop());");
1.91 break;
1.92 - case ByteCodes.bc_ireturn:
1.93 - case ByteCodes.bc_lreturn:
1.94 - case ByteCodes.bc_freturn:
1.95 - case ByteCodes.bc_dreturn:
1.96 + case bc_ireturn:
1.97 + case bc_lreturn:
1.98 + case bc_freturn:
1.99 + case bc_dreturn:
1.100 out.append("return stack.pop();");
1.101 break;
1.102 + case bc_i2l:
1.103 + case bc_i2f:
1.104 + case bc_i2d:
1.105 + case bc_l2i:
1.106 + case bc_l2f:
1.107 + case bc_l2d:
1.108 + case bc_f2i:
1.109 + case bc_f2l:
1.110 + case bc_f2d:
1.111 + case bc_d2i:
1.112 + case bc_d2l:
1.113 + case bc_d2f:
1.114 + case bc_i2b:
1.115 + case bc_i2c:
1.116 + case bc_i2s:
1.117 + out.append("/* number conversion */");
1.118 + break;
1.119 }
1.120 out.append("/*");
1.121 for (int j = prev; j <= i; j++) {
2.1 --- a/src/test/java/org/apidesign/java4browser/StaticMethod.java Mon Aug 27 05:17:08 2012 +0200
2.2 +++ b/src/test/java/org/apidesign/java4browser/StaticMethod.java Mon Aug 27 05:47:44 2012 +0200
2.3 @@ -28,4 +28,7 @@
2.4 public static float power(float x) {
2.5 return x * x;
2.6 }
2.7 + public static double minus(double x, long y) {
2.8 + return x - y;
2.9 + }
2.10 }
3.1 --- a/src/test/java/org/apidesign/java4browser/StaticMethodTest.java Mon Aug 27 05:17:08 2012 +0200
3.2 +++ b/src/test/java/org/apidesign/java4browser/StaticMethodTest.java Mon Aug 27 05:47:44 2012 +0200
3.3 @@ -32,23 +32,58 @@
3.4 */
3.5 public class StaticMethodTest {
3.6 @Test public void threePlusFour() throws Exception {
3.7 - Invocable i = compileClass("StaticMethod.class");
3.8 -
3.9 - Object ret = i.invokeFunction("org_apidesign_java4browser_StaticMethod_sumIII", 3, 4);
3.10 - assertEquals(ret, Double.valueOf(7), "Should be seven");
3.11 + assertExec(
3.12 + "Should be seven",
3.13 + "org_apidesign_java4browser_StaticMethod_sumIII",
3.14 + Double.valueOf(7),
3.15 + 3, 4
3.16 + );
3.17 }
3.18
3.19 @Test public void powerOfThree() throws Exception {
3.20 - Invocable i = compileClass("StaticMethod.class");
3.21 -
3.22 - Object ret = i.invokeFunction("org_apidesign_java4browser_StaticMethod_powerFF", 3.0f);
3.23 - assertEquals(ret, Double.valueOf(9), "Should be nine");
3.24 + assertExec(
3.25 + "Should be nine",
3.26 + "org_apidesign_java4browser_StaticMethod_powerFF",
3.27 + Double.valueOf(9),
3.28 + 3.0f
3.29 + );
3.30 }
3.31
3.32 - static Invocable compileClass(String name) throws ScriptException, IOException {
3.33 + @Test public void doubleWithoutLong() throws Exception {
3.34 + assertExec(
3.35 + "Should be two",
3.36 + "org_apidesign_java4browser_StaticMethod_minusDDJ",
3.37 + Double.valueOf(2),
3.38 + 3.0d, 1l
3.39 + );
3.40 + }
3.41 +
3.42 + private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception {
3.43 + StringBuilder sb = new StringBuilder();
3.44 + Invocable i = compileClass("StaticMethod.class", sb);
3.45 +
3.46 + Object ret = null;
3.47 + try {
3.48 + ret = i.invokeFunction(methodName, args);
3.49 + } catch (NoSuchMethodException ex) {
3.50 + fail("Cannot find method in " + sb, ex);
3.51 + }
3.52 + if (ret == null && expRes == null) {
3.53 + return;
3.54 + }
3.55 + if (expRes.equals(ret)) {
3.56 + return;
3.57 + }
3.58 + assertEquals(ret, expRes, msg + "\n" + sb);
3.59 +
3.60 + }
3.61 +
3.62 + static Invocable compileClass(String name, StringBuilder sb) throws ScriptException, IOException {
3.63 InputStream is = StaticMethodTest.class.getResourceAsStream(name);
3.64 assertNotNull(is, "Class file found");
3.65 - StringBuilder sb = new StringBuilder();
3.66 + if (sb == null) {
3.67 + sb = new StringBuilder();
3.68 + }
3.69 ByteCodeToJavaScript.compile(name, is, sb);
3.70 ScriptEngineManager sem = new ScriptEngineManager();
3.71 ScriptEngine js = sem.getEngineByExtension("js");