# HG changeset patch # User Jaroslav Tulach # Date 1350482344 -7200 # Node ID 3d5597011af098a7128a3ba510e95a798142bf2a # Parent a0505844750a9b9168f0dec0a48bd5010871be9a Support for switch diff -r a0505844750a -r 3d5597011af0 vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Oct 16 18:04:11 2012 +0200 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Wed Oct 17 15:59:04 2012 +0200 @@ -569,6 +569,43 @@ i += 2; break; } + case bc_lookupswitch: { + int table = (i - 1) / 4 * 4 + 4; + int dflt = i + readInt4(byteCodes, table); + table += 4; + int n = readInt4(byteCodes, table); + table += 4; + out.append("switch (stack.pop()) {\n"); + while (n-- > 0) { + int cnstnt = readInt4(byteCodes, table); + table += 4; + int offset = i + readInt4(byteCodes, table); + table += 4; + out.append(" case " + cnstnt).append(": gt = " + offset).append("; continue;\n"); + } + out.append(" default: gt = " + dflt).append("; continue;\n}"); + i = table - 1; + break; + } + case bc_tableswitch: { + int table = (i - 1) / 4 * 4 + 4; + int dflt = i + readInt4(byteCodes, table); + table += 4; + int low = readInt4(byteCodes, table); + table += 4; + int high = readInt4(byteCodes, table); + table += 4; + out.append("switch (stack.pop()) {\n"); + while (low <= high) { + int offset = i + readInt4(byteCodes, table); + table += 4; + out.append(" case " + low).append(": gt = " + offset).append("; continue;\n"); + low++; + } + out.append(" default: gt = " + dflt).append("; continue;\n}"); + i = table - 1; + break; + } case bc_invokeinterface: { i = invokeVirtualMethod(byteCodes, i) + 2; break; @@ -731,6 +768,13 @@ final int indxLo = byteCodes[offsetInstruction + 2]; return (indxHi & 0xffffff00) | (indxLo & 0xff); } + private int readInt4(byte[] byteCodes, int offsetInstruction) { + final int d = byteCodes[offsetInstruction + 0] << 24; + final int c = byteCodes[offsetInstruction + 1] << 16; + final int b = byteCodes[offsetInstruction + 2] << 8; + final int a = byteCodes[offsetInstruction + 3]; + return (d & 0xff000000) | (c & 0xff0000) | (b & 0xff00) | (a & 0xff); + } private static int countArgs(String descriptor, boolean[] hasReturnType, StringBuilder sig) { int cnt = 0; diff -r a0505844750a -r 3d5597011af0 vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java Tue Oct 16 18:04:11 2012 +0200 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethod.java Wed Oct 17 15:59:04 2012 +0200 @@ -118,6 +118,23 @@ throw new IllegalStateException(); } + public static String swtch(int what) { + switch (what) { + case 0: return "Jarda"; + case 1: return "Darda"; + case 2: return "Parda"; + default: return "Marda"; + } + } + public static String swtch2(int what) { + switch (what) { + case 0: return "Jarda"; + case 11: return "Darda"; + case 22: return "Parda"; + default: return "Marda"; + } + } + static { // check order of initializers StaticUse.NON_NULL.equals(new Object()); diff -r a0505844750a -r 3d5597011af0 vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java --- a/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Tue Oct 16 18:04:11 2012 +0200 +++ b/vm/src/test/java/org/apidesign/vm4brwsr/StaticMethodTest.java Wed Oct 17 15:59:04 2012 +0200 @@ -211,6 +211,40 @@ ); } + @Test public void switchJarda() throws Exception { + assertExec( + "The expected value", + "org_apidesign_vm4brwsr_StaticMethod_swtchLjava_lang_StringI", + "Jarda", + 0 + ); + } + + @Test public void switchDarda() throws Exception { + assertExec( + "The expected value", + "org_apidesign_vm4brwsr_StaticMethod_swtchLjava_lang_StringI", + "Darda", + 1 + ); + } + @Test public void switchParda() throws Exception { + assertExec( + "The expected value", + "org_apidesign_vm4brwsr_StaticMethod_swtch2Ljava_lang_StringI", + "Parda", + 22 + ); + } + @Test public void switchMarda() throws Exception { + assertExec( + "The expected value", + "org_apidesign_vm4brwsr_StaticMethod_swtchLjava_lang_StringI", + "Marda", + -433 + ); + } + private static CharSequence codeSeq; private static Invocable code;