# HG changeset patch # User Jaroslav Tulach # Date 1346039264 -7200 # Node ID 4679bf342a1f9b205df3e3347a7c7be5d20ced71 # Parent 48b1dce93691ce4ad0f5f12e0f41fbbc17faa3ba Support for subtraction. Double occupies two slots. static import of byte codes. diff -r 48b1dce93691 -r 4679bf342a1f src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java --- a/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Mon Aug 27 05:17:08 2012 +0200 +++ b/src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java Mon Aug 27 05:47:44 2012 +0200 @@ -20,7 +20,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; -import org.netbeans.modules.classfile.ByteCodes; +import static org.netbeans.modules.classfile.ByteCodes.*; import org.netbeans.modules.classfile.ClassFile; import org.netbeans.modules.classfile.Code; import org.netbeans.modules.classfile.Method; @@ -67,10 +67,16 @@ } out.append('('); String space = ""; - for (int i = 0; i < args.size(); i++) { + for (int index = 0, i = 0; i < args.size(); i++) { out.append(space); - out.append("arg").append(String.valueOf(i)); + out.append("arg").append(String.valueOf(index)); space = ","; + final String desc = args.get(i).getDescriptor(); + if ("D".equals(desc)) { + index += 2; + } else { + index++; + } } out.append(") {").append("\n var "); final Code code = m.getCode(); @@ -94,38 +100,68 @@ out.append(" "); final int c = (byteCodes[i] + 256) % 256; switch (c) { - case ByteCodes.bc_aload_0: - case ByteCodes.bc_iload_0: - case ByteCodes.bc_lload_0: - case ByteCodes.bc_fload_0: - case ByteCodes.bc_dload_0: + case bc_aload_0: + case bc_iload_0: + case bc_lload_0: + case bc_fload_0: + case bc_dload_0: out.append("stack.push(arg0);"); break; - case ByteCodes.bc_aload_1: - case ByteCodes.bc_iload_1: - case ByteCodes.bc_lload_1: - case ByteCodes.bc_fload_1: - case ByteCodes.bc_dload_1: + case bc_aload_1: + case bc_iload_1: + case bc_lload_1: + case bc_fload_1: + case bc_dload_1: out.append("stack.push(arg1);"); break; - case ByteCodes.bc_iadd: - case ByteCodes.bc_ladd: - case ByteCodes.bc_fadd: - case ByteCodes.bc_dadd: + case bc_aload_2: + case bc_iload_2: + case bc_lload_2: + case bc_fload_2: + case bc_dload_2: + out.append("stack.push(arg2);"); + break; + case bc_iadd: + case bc_ladd: + case bc_fadd: + case bc_dadd: out.append("stack.push(stack.pop() + stack.pop());"); break; - case ByteCodes.bc_imul: - case ByteCodes.bc_lmul: - case ByteCodes.bc_fmul: - case ByteCodes.bc_dmul: + case bc_isub: + case bc_lsub: + case bc_fsub: + case bc_dsub: + out.append("stack.push(- stack.pop() + stack.pop());"); + break; + case bc_imul: + case bc_lmul: + case bc_fmul: + case bc_dmul: out.append("stack.push(stack.pop() * stack.pop());"); break; - case ByteCodes.bc_ireturn: - case ByteCodes.bc_lreturn: - case ByteCodes.bc_freturn: - case ByteCodes.bc_dreturn: + case bc_ireturn: + case bc_lreturn: + case bc_freturn: + case bc_dreturn: out.append("return stack.pop();"); break; + case bc_i2l: + case bc_i2f: + case bc_i2d: + case bc_l2i: + case bc_l2f: + case bc_l2d: + case bc_f2i: + case bc_f2l: + case bc_f2d: + case bc_d2i: + case bc_d2l: + case bc_d2f: + case bc_i2b: + case bc_i2c: + case bc_i2s: + out.append("/* number conversion */"); + break; } out.append("/*"); for (int j = prev; j <= i; j++) { diff -r 48b1dce93691 -r 4679bf342a1f src/test/java/org/apidesign/java4browser/StaticMethod.java --- a/src/test/java/org/apidesign/java4browser/StaticMethod.java Mon Aug 27 05:17:08 2012 +0200 +++ b/src/test/java/org/apidesign/java4browser/StaticMethod.java Mon Aug 27 05:47:44 2012 +0200 @@ -28,4 +28,7 @@ public static float power(float x) { return x * x; } + public static double minus(double x, long y) { + return x - y; + } } diff -r 48b1dce93691 -r 4679bf342a1f src/test/java/org/apidesign/java4browser/StaticMethodTest.java --- a/src/test/java/org/apidesign/java4browser/StaticMethodTest.java Mon Aug 27 05:17:08 2012 +0200 +++ b/src/test/java/org/apidesign/java4browser/StaticMethodTest.java Mon Aug 27 05:47:44 2012 +0200 @@ -32,23 +32,58 @@ */ public class StaticMethodTest { @Test public void threePlusFour() throws Exception { - Invocable i = compileClass("StaticMethod.class"); - - Object ret = i.invokeFunction("org_apidesign_java4browser_StaticMethod_sumIII", 3, 4); - assertEquals(ret, Double.valueOf(7), "Should be seven"); + assertExec( + "Should be seven", + "org_apidesign_java4browser_StaticMethod_sumIII", + Double.valueOf(7), + 3, 4 + ); } @Test public void powerOfThree() throws Exception { - Invocable i = compileClass("StaticMethod.class"); - - Object ret = i.invokeFunction("org_apidesign_java4browser_StaticMethod_powerFF", 3.0f); - assertEquals(ret, Double.valueOf(9), "Should be nine"); + assertExec( + "Should be nine", + "org_apidesign_java4browser_StaticMethod_powerFF", + Double.valueOf(9), + 3.0f + ); } - static Invocable compileClass(String name) throws ScriptException, IOException { + @Test public void doubleWithoutLong() throws Exception { + assertExec( + "Should be two", + "org_apidesign_java4browser_StaticMethod_minusDDJ", + Double.valueOf(2), + 3.0d, 1l + ); + } + + private static void assertExec(String msg, String methodName, Object expRes, Object... args) throws Exception { + StringBuilder sb = new StringBuilder(); + Invocable i = compileClass("StaticMethod.class", sb); + + Object ret = null; + try { + ret = i.invokeFunction(methodName, args); + } catch (NoSuchMethodException ex) { + fail("Cannot find method in " + sb, ex); + } + if (ret == null && expRes == null) { + return; + } + if (expRes.equals(ret)) { + return; + } + assertEquals(ret, expRes, msg + "\n" + sb); + + } + + static Invocable compileClass(String name, StringBuilder sb) throws ScriptException, IOException { InputStream is = StaticMethodTest.class.getResourceAsStream(name); assertNotNull(is, "Class file found"); - StringBuilder sb = new StringBuilder(); + if (sb == null) { + sb = new StringBuilder(); + } ByteCodeToJavaScript.compile(name, is, sb); ScriptEngineManager sem = new ScriptEngineManager(); ScriptEngine js = sem.getEngineByExtension("js");