Support for switch
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Wed, 17 Oct 2012 15:59:04 +0200
changeset 1153d5597011af0
parent 114 a0505844750a
child 116 033d51e026b0
Support for switch
vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java
vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java
vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java
     1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Tue Oct 16 18:04:11 2012 +0200
     1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java	Wed Oct 17 15:59:04 2012 +0200
     1.3 @@ -569,6 +569,43 @@
     1.4                      i += 2;
     1.5                      break;
     1.6                  }
     1.7 +                case bc_lookupswitch: {
     1.8 +                    int table = (i - 1) / 4 * 4 + 4;
     1.9 +                    int dflt = i + readInt4(byteCodes, table);
    1.10 +                    table += 4;
    1.11 +                    int n = readInt4(byteCodes, table);
    1.12 +                    table += 4;
    1.13 +                    out.append("switch (stack.pop()) {\n");
    1.14 +                    while (n-- > 0) {
    1.15 +                        int cnstnt = readInt4(byteCodes, table);
    1.16 +                        table += 4;
    1.17 +                        int offset = i + readInt4(byteCodes, table);
    1.18 +                        table += 4;
    1.19 +                        out.append("  case " + cnstnt).append(": gt = " + offset).append("; continue;\n");
    1.20 +                    }
    1.21 +                    out.append("  default: gt = " + dflt).append("; continue;\n}");
    1.22 +                    i = table - 1;
    1.23 +                    break;
    1.24 +                }
    1.25 +                case bc_tableswitch: {
    1.26 +                    int table = (i - 1) / 4 * 4 + 4;
    1.27 +                    int dflt = i + readInt4(byteCodes, table);
    1.28 +                    table += 4;
    1.29 +                    int low = readInt4(byteCodes, table);
    1.30 +                    table += 4;
    1.31 +                    int high = readInt4(byteCodes, table);
    1.32 +                    table += 4;
    1.33 +                    out.append("switch (stack.pop()) {\n");
    1.34 +                    while (low <= high) {
    1.35 +                        int offset = i + readInt4(byteCodes, table);
    1.36 +                        table += 4;
    1.37 +                        out.append("  case " + low).append(": gt = " + offset).append("; continue;\n");
    1.38 +                        low++;
    1.39 +                    }
    1.40 +                    out.append("  default: gt = " + dflt).append("; continue;\n}");
    1.41 +                    i = table - 1;
    1.42 +                    break;
    1.43 +                }
    1.44                  case bc_invokeinterface: {
    1.45                      i = invokeVirtualMethod(byteCodes, i) + 2;
    1.46                      break;
    1.47 @@ -731,6 +768,13 @@
    1.48          final int indxLo = byteCodes[offsetInstruction + 2];
    1.49          return (indxHi & 0xffffff00) | (indxLo & 0xff);
    1.50      }
    1.51 +    private int readInt4(byte[] byteCodes, int offsetInstruction) {
    1.52 +        final int d = byteCodes[offsetInstruction + 0] << 24;
    1.53 +        final int c = byteCodes[offsetInstruction + 1] << 16;
    1.54 +        final int b = byteCodes[offsetInstruction + 2] << 8;
    1.55 +        final int a = byteCodes[offsetInstruction + 3];
    1.56 +        return (d & 0xff000000) | (c & 0xff0000) | (b & 0xff00) | (a & 0xff);
    1.57 +    }
    1.58      
    1.59      private static int countArgs(String descriptor, boolean[] hasReturnType, StringBuilder sig) {
    1.60          int cnt = 0;
     2.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java	Tue Oct 16 18:04:11 2012 +0200
     2.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java	Wed Oct 17 15:59:04 2012 +0200
     2.3 @@ -118,6 +118,23 @@
     2.4          throw new IllegalStateException();
     2.5      }
     2.6      
     2.7 +    public static String swtch(int what) {
     2.8 +        switch (what) {
     2.9 +            case 0: return "Jarda";
    2.10 +            case 1: return "Darda";
    2.11 +            case 2: return "Parda";
    2.12 +            default: return "Marda";
    2.13 +        }
    2.14 +    }
    2.15 +    public static String swtch2(int what) {
    2.16 +        switch (what) {
    2.17 +            case 0: return "Jarda";
    2.18 +            case 11: return "Darda";
    2.19 +            case 22: return "Parda";
    2.20 +            default: return "Marda";
    2.21 +        }
    2.22 +    }
    2.23 +    
    2.24      static {
    2.25          // check order of initializers
    2.26          StaticUse.NON_NULL.equals(new Object());
     3.1 --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java	Tue Oct 16 18:04:11 2012 +0200
     3.2 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java	Wed Oct 17 15:59:04 2012 +0200
     3.3 @@ -211,6 +211,40 @@
     3.4          );
     3.5      }
     3.6      
     3.7 +    @Test public void switchJarda() throws Exception {
     3.8 +        assertExec(
     3.9 +            "The expected value",
    3.10 +            "org_apidesign_vm4brwsr_StaticMethod_swtchLjava_lang_StringI",
    3.11 +            "Jarda",
    3.12 +            0
    3.13 +        );
    3.14 +    }
    3.15 +    
    3.16 +    @Test public void switchDarda() throws Exception {
    3.17 +        assertExec(
    3.18 +            "The expected value",
    3.19 +            "org_apidesign_vm4brwsr_StaticMethod_swtchLjava_lang_StringI",
    3.20 +            "Darda",
    3.21 +            1
    3.22 +        );
    3.23 +    }
    3.24 +    @Test public void switchParda() throws Exception {
    3.25 +        assertExec(
    3.26 +            "The expected value",
    3.27 +            "org_apidesign_vm4brwsr_StaticMethod_swtch2Ljava_lang_StringI",
    3.28 +            "Parda",
    3.29 +            22
    3.30 +        );
    3.31 +    }
    3.32 +    @Test public void switchMarda() throws Exception {
    3.33 +        assertExec(
    3.34 +            "The expected value",
    3.35 +            "org_apidesign_vm4brwsr_StaticMethod_swtchLjava_lang_StringI",
    3.36 +            "Marda",
    3.37 +            -433
    3.38 +        );
    3.39 +    }
    3.40 +    
    3.41      private static CharSequence codeSeq;
    3.42      private static Invocable code;
    3.43