changeset 23038:71bb0eb7b094

Add SWITCH bytecode to the bytecode interpreter partial evaluation tests.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 20 Nov 2015 00:44:28 +0100
parents a54b0edb0aea
children af898ba7cfda
files graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/BytecodeInterpreterPartialEvaluationTest.java
diffstat 1 files changed, 60 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/BytecodeInterpreterPartialEvaluationTest.java	Fri Nov 20 00:43:44 2015 +0100
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/BytecodeInterpreterPartialEvaluationTest.java	Fri Nov 20 00:44:28 2015 +0100
@@ -65,6 +65,7 @@
         public static final byte POP = 4;
         public static final byte JMP = 5;
         public static final byte DUP = 6;
+        public static final byte SWITCH = 7;
     }
 
     public static boolean TRACE = false;
@@ -120,7 +121,7 @@
             trace("Start program");
             int topOfStack = -1;
             int bci = 0;
-            while (true) {
+            outer: while (true) {
                 CompilerAsserts.partialEvaluationConstant(bci);
                 byte bc = bytecodes[bci];
                 byte value = 0;
@@ -156,6 +157,40 @@
                             continue;
                         }
 
+                    case Bytecode.SWITCH:
+                        trace("%d (%d): SWITCH", bci, topOfStack);
+                        {
+                            int switchValue = getInt(frame, topOfStack--);
+                            byte switchTargetCount = bytecodes[bci + 1];
+                            int i = 0;
+                            while (true) {
+                                CompilerAsserts.partialEvaluationConstant(i);
+                                if (switchValue == i) {
+                                    CompilerAsserts.partialEvaluationConstant(i);
+                                    CompilerAsserts.partialEvaluationConstant(bci);
+                                    bci = bytecodes[bci + i + 2];
+                                    // Need this seemingly useless condition here for two reasons:
+                                    // 1. Bytecode analysis will consider the current block as
+                                    // being within the inner loop.
+                                    // 2. The if body will be an empty block that directly
+                                    // jumps to the begin of the outer loop.
+                                    if (i != -1) {
+                                        continue outer;
+                                    }
+                                }
+
+                                CompilerAsserts.partialEvaluationConstant(switchTargetCount);
+                                CompilerAsserts.partialEvaluationConstant(i);
+                                i = i + 1;
+                                if (i == switchTargetCount) {
+                                    break;
+                                }
+                            }
+                            // Continue with the code after the switch.
+                            bci += switchTargetCount + 1;
+                            continue;
+                        }
+
                     case Bytecode.POP:
                         trace("%d (%d): POP", bci, topOfStack);
                         topOfStack--;
@@ -183,7 +218,8 @@
     }
 
     private static void assertReturns42(RootNode program) {
-        Assert.assertEquals(Integer.valueOf(42), Truffle.getRuntime().createCallTarget(program).call());
+        Object result = Truffle.getRuntime().createCallTarget(program).call();
+        Assert.assertEquals(Integer.valueOf(42), result);
     }
 
     private void assertPartialEvalEqualsAndRunsCorrect(RootNode program) {
@@ -553,4 +589,26 @@
         program.execute(Truffle.getRuntime().createVirtualFrame(new Object[1], fd));
         assertPartialEvalEqualsAndRunsCorrect(program);
     }
+
+    @Test
+    public void simpleSwitchProgram() {
+        byte[] bytecodes = new byte[]{
+        /* 0: */Bytecode.CONST,
+        /* 1: */1,
+        /* 2: */Bytecode.SWITCH,
+        /* 3: */2,
+        /* 4: */9,
+        /* 5: */12,
+        /* 6: */Bytecode.CONST,
+        /* 7: */40,
+        /* 8: */Bytecode.RETURN,
+        /* 9: */Bytecode.CONST,
+        /* 10: */41,
+        /* 11: */Bytecode.RETURN,
+        /* 12: */Bytecode.CONST,
+        /* 13: */42,
+        /* 14: */Bytecode.RETURN};
+        Program program = new Program("simpleSwitchProgram", bytecodes, 0, 3);
+        assertPartialEvalEqualsAndRunsCorrect(program);
+    }
 }