Support for subtraction. Double occupies two slots. static import of byte codes.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Mon, 27 Aug 2012 05:47:44 +0200
changeset 24679bf342a1f
parent 1 48b1dce93691
child 3 e44f0155d946
Support for subtraction. Double occupies two slots. static import of byte codes.
src/main/java/org/apidesign/java4browser/ByteCodeToJavaScript.java
src/test/java/org/apidesign/java4browser/StaticMethod.java
src/test/java/org/apidesign/java4browser/StaticMethodTest.java
     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");