changeset 13882:afd6fa5e8229

SL: Feedback from reviewers
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 05 Feb 2014 08:02:15 -0800
parents 272a166a9574
children 812f3155efba
files graal/com.oracle.truffle.sl.test/tests/LoopCall.sl graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.output graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.sl graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.sl graal/com.oracle.truffle.sl.test/tests/LoopPrint.sl graal/com.oracle.truffle.sl.test/tests/error/TypeError03.output graal/com.oracle.truffle.sl.test/tests/error/TypeError03.sl graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output graal/com.oracle.truffle.sl.test/tests/error/TypeError04.sl graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLCallNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java
diffstat 28 files changed, 169 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.sl.test/tests/LoopCall.sl	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopCall.sl	Wed Feb 05 08:02:15 2014 -0800
@@ -3,13 +3,18 @@
 }
 
 function loop(n) {
-  i = 0;  
+  i = 0;
   while (i < n) {  
     i = add(i, 1);  
-  }  
+  }
   return i;
-}  
+}
 
 function main() {
+  i = 0;
+  while (i < 20) {
+    loop(1000);
+    i = i + 1;
+  }
   println(loop(1000));  
-}  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.output	Wed Feb 05 08:02:15 2014 -0800
@@ -0,0 +1,1 @@
+1000
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.sl	Wed Feb 05 08:02:15 2014 -0800
@@ -0,0 +1,21 @@
+function add(a, b) {
+  return a + b;
+}
+
+function loop(n) {
+  i = 0;  
+  while (i < n) {  
+    i = add(i, 1);  
+  }  
+  return i;
+}  
+
+function main() {
+  i = 0;
+  while (i < 20) {
+    loop(1000);
+    i = i + 1;
+  }
+  add("a", "b");
+  println(loop(1000));  
+}  
--- a/graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.sl	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.sl	Wed Feb 05 08:02:15 2014 -0800
@@ -3,14 +3,20 @@
 }
 
 function loop(n) {
-  i = 0;  
-  while (i < n) {  
-    i = add(i, 1);  
-  }  
+  i = 0;
+  while (i < n) {
+    i = add(i, 1); 
+  }
   return i;
-}  
+}
 
 function main() {
   add("a", "b");
+
+  i = 0;
+  while (i < 20) {
+    loop(1000);
+    i = i + 1;
+  }
   println(loop(1000));  
-}  
+}
--- a/graal/com.oracle.truffle.sl.test/tests/LoopPrint.sl	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl.test/tests/LoopPrint.sl	Wed Feb 05 08:02:15 2014 -0800
@@ -7,5 +7,10 @@
 }  
 
 function main() {
+  i = 0;
+  while (i < 20) {
+    loop(1000);
+    i = i + 1;
+  }
   println(loop(1000));  
 }  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError03.output	Wed Feb 05 08:02:15 2014 -0800
@@ -0,0 +1,1 @@
+Type error at TypeError03.sl line 2 col 7: operation "&&" not defined for String "4", ANY
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError03.sl	Wed Feb 05 08:02:15 2014 -0800
@@ -0,0 +1,3 @@
+function main() {  
+  "4" && 4;  
+}  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output	Wed Feb 05 08:02:15 2014 -0800
@@ -0,0 +1,1 @@
+Type error at TypeError04.sl line 2 col 11: operation "||" not defined for Boolean false, Number 4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl.test/tests/error/TypeError04.sl	Wed Feb 05 08:02:15 2014 -0800
@@ -0,0 +1,3 @@
+function main() {  
+  (1 > 2) || 4;  
+}  
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java	Wed Feb 05 08:02:15 2014 -0800
@@ -183,8 +183,10 @@
     }
 
     /**
-     * Dumps the AST of all functions to the IGV visualizer, via a socket connection. IGV can be
-     * started with the mx command "mx igv". Optionally, also prints the ASTs to the console.
+     * When dumpASTToIGV is true: dumps the AST of all functions to the IGV visualizer, via a socket
+     * connection. IGV can be started with the mx command "mx igv".
+     * <p>
+     * When printASTToLog is true: prints the ASTs to the console.
      */
     private static void printScript(String groupName, SLContext context, PrintStream logOutput, boolean printASTToLog, boolean dumpASTToIGV) {
         if (dumpASTToIGV) {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java	Wed Feb 05 08:02:15 2014 -0800
@@ -22,10 +22,12 @@
  */
 package com.oracle.truffle.sl.builtins;
 
+import com.oracle.truffle.api.CompilerDirectives.SlowPath;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.sl.parser.*;
+import com.oracle.truffle.sl.runtime.*;
 
 /**
  * Builtin function to define (or redefine) functions. The provided source code is parsed the same
@@ -36,9 +38,14 @@
 
     @Specialization
     public String defineFunction(String code) {
-        Source source = getContext().getSourceManager().get("[defineFunction]", code);
+        return doDefineFunction(getContext(), code);
+    }
+
+    @SlowPath
+    private static String doDefineFunction(SLContext context, String code) {
+        Source source = context.getSourceManager().get("[defineFunction]", code);
         /* The same parsing code as for parsing the initial source. */
-        Parser.parseSL(getContext(), source);
+        Parser.parseSL(context, source);
         return code;
     }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java	Wed Feb 05 08:02:15 2014 -0800
@@ -22,6 +22,9 @@
  */
 package com.oracle.truffle.sl.builtins;
 
+import java.io.*;
+
+import com.oracle.truffle.api.CompilerDirectives.SlowPath;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.sl.runtime.*;
@@ -30,31 +33,55 @@
  * Builtin function to write a value to the {@link SLContext#getOutput() standard output}. The
  * different specialization leverage the typed {@code println} methods available in Java, i.e.,
  * primitive values are printed without converting them to a {@link String} first.
+ * <p>
+ * Printing involves a lot of Java code, so we need to tell the optimizing system that it should not
+ * unconditionally inline everything reachable from the println() method. This is done via the
+ * {@link SlowPath} annotations.
  */
 @NodeInfo(shortName = "println")
 public abstract class SLPrintlnBuiltin extends SLBuiltinNode {
 
     @Specialization
     public long println(long value) {
-        getContext().getOutput().println(value);
+        doPrint(getContext().getOutput(), value);
         return value;
     }
 
+    @SlowPath
+    private static void doPrint(PrintStream out, long value) {
+        out.println(value);
+    }
+
     @Specialization
     public boolean println(boolean value) {
-        getContext().getOutput().println(value);
+        doPrint(getContext().getOutput(), value);
         return value;
     }
 
+    @SlowPath
+    private static void doPrint(PrintStream out, boolean value) {
+        out.println(value);
+    }
+
     @Specialization
     public String println(String value) {
-        getContext().getOutput().println(value);
+        doPrint(getContext().getOutput(), value);
         return value;
     }
 
+    @SlowPath
+    private static void doPrint(PrintStream out, String value) {
+        out.println(value);
+    }
+
     @Specialization
     public Object println(Object value) {
-        getContext().getOutput().println(value);
+        doPrint(getContext().getOutput(), value);
         return value;
     }
+
+    @SlowPath
+    private static void doPrint(PrintStream out, Object value) {
+        out.println(value);
+    }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java	Wed Feb 05 08:02:15 2014 -0800
@@ -24,6 +24,7 @@
 
 import java.io.*;
 
+import com.oracle.truffle.api.CompilerDirectives.SlowPath;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.sl.*;
@@ -37,17 +38,22 @@
 
     @Specialization
     public String readln() {
+        String result = doRead(getContext().getInput());
+        if (result == null) {
+            /*
+             * We do not have a sophisticated end of file handling, so returning an empty string is
+             * a reasonable alternative. Note that the Java null value should never be used, since
+             * it can interfere with the specialization logic in generated source code.
+             */
+            result = "";
+        }
+        return result;
+    }
+
+    @SlowPath
+    private static String doRead(BufferedReader in) {
         try {
-            String result = getContext().getInput().readLine();
-            if (result == null) {
-                /*
-                 * We do not have a sophisticated end of file handling, so returning an empty string
-                 * is a reasonable alternative. Note that the Java null value should never be used,
-                 * since it can interfere with the specialization logic in generated source code.
-                 */
-                result = "";
-            }
-            return result;
+            return in.readLine();
         } catch (IOException ex) {
             throw new SLException(ex.getMessage());
         }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -26,8 +26,8 @@
 
 /**
  * Utility base class for operations that take two arguments (per convention called "left" and
- * "right). For concrete subclasses of this class, the Truffle DSL creates two child fields, and the
- * necessary constructors and logic to set them.
+ * "right"). For concrete subclasses of this class, the Truffle DSL creates two child fields, and
+ * the necessary constructors and logic to set them.
  */
 @NodeChildren({@NodeChild("leftNode"), @NodeChild("rightNode")})
 public abstract class SLBinaryNode extends SLExpressionNode {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java	Wed Feb 05 08:02:15 2014 -0800
@@ -29,10 +29,10 @@
 import com.oracle.truffle.sl.runtime.*;
 
 /**
- * The type system of SL, as explained in {@link SLMain}. Based on the annotation {@link TypeSystem}
- * , the Truffle DSL generates the subclass {@link SLTypesGen} with type test and type conversion
- * methods for all types. In this class, we only cover types where the automatically generated ones
- * would not be sufficient.
+ * The type system of SL, as explained in {@link SLMain}. Based on the {@link TypeSystem}
+ * annotation, the Truffle DSL generates the subclass {@link SLTypesGen} with type test and type
+ * conversion methods for all types. In this class, we only cover types where the automatically
+ * generated ones would not be sufficient.
  */
 @TypeSystem({long.class, BigInteger.class, boolean.class, String.class, SLFunction.class, SLNull.class})
 public abstract class SLTypes {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLCallNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLCallNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes.call;
 
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
@@ -57,6 +58,14 @@
     public Object executeGeneric(VirtualFrame frame) {
         SLFunction function = evaluateFunction(frame);
 
+        /*
+         * The number of arguments is constant for one call node. During compilation, the loop is
+         * unrolled and the execute methods of all arguments are inlined. This is triggered by the
+         * ExplodeLoop annotation on the method. The compiler assertion below illustrates that the
+         * array length is really constant.
+         */
+        CompilerAsserts.compilationConstant(argumentNodes.length);
+
         Object[] argumentValues = new Object[argumentNodes.length];
         for (int i = 0; i < argumentNodes.length; i++) {
             argumentValues[i] = argumentNodes[i].executeGeneric(frame);
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -22,6 +22,7 @@
  */
 package com.oracle.truffle.sl.nodes.controlflow;
 
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.sl.nodes.*;
@@ -30,7 +31,7 @@
  * A statement node that just executes a list of other statements.
  */
 @NodeInfo(shortName = "block")
-public class SLBlockNode extends SLStatementNode {
+public final class SLBlockNode extends SLStatementNode {
 
     /**
      * The array of child nodes. The annotation {@link com.oracle.truffle.api.nodes.Node.Children
@@ -55,6 +56,12 @@
     @Override
     @ExplodeLoop
     public void executeVoid(VirtualFrame frame) {
+        /*
+         * This assertion illustrates that the arryay length is really a constant during
+         * compilation.
+         */
+        CompilerAsserts.compilationConstant(bodyNodes.length);
+
         for (SLStatementNode statement : bodyNodes) {
             statement.executeVoid(frame);
         }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -36,7 +36,7 @@
  * {@link SLNull#SINGLETON default null value}.
  */
 @NodeInfo(shortName = "body")
-public class SLFunctionBodyNode extends SLExpressionNode {
+public final class SLFunctionBodyNode extends SLExpressionNode {
 
     /** The body of the function. */
     @Child private SLStatementNode bodyNode;
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -29,7 +29,7 @@
 import com.oracle.truffle.sl.nodes.*;
 
 @NodeInfo(shortName = "if")
-public class SLIfNode extends SLStatementNode {
+public final class SLIfNode extends SLStatementNode {
 
     /**
      * The condition of the {@code if}. This in a {@link SLExpressionNode} because we require a
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -35,7 +35,7 @@
  * the return value.
  */
 @NodeInfo(shortName = "return")
-public class SLReturnNode extends SLStatementNode {
+public final class SLReturnNode extends SLStatementNode {
 
     @Child private SLExpressionNode valueNode;
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -30,7 +30,7 @@
 import com.oracle.truffle.sl.nodes.*;
 
 @NodeInfo(shortName = "while")
-public class SLWhileNode extends SLStatementNode {
+public final class SLWhileNode extends SLStatementNode {
 
     /**
      * The condition of the loop. This in a {@link SLExpressionNode} because we require a result
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -29,13 +29,16 @@
 import com.oracle.truffle.sl.nodes.*;
 
 /**
- * This class is similar to the extensively documented {@link SLAddNode}.
+ * This class is similar to the extensively documented {@link SLAddNode}. Divisions by 0 throw the
+ * same {@link ArithmeticException exception} as in Java, SL has no special handling for it to keep
+ * the code simple.
  */
 @NodeInfo(shortName = "/")
 public abstract class SLDivNode extends SLBinaryNode {
 
-    @Specialization(rewriteOn = ArithmeticException.class)
+    @Specialization
     protected long div(long left, long right) {
+        /* No overflow is possible on a division. */
         return left / right;
     }
 
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -30,7 +30,7 @@
 import com.oracle.truffle.sl.runtime.*;
 
 /**
- * The {@code ==} operator of SL is defined on all types. Therefore, we need a (@link
+ * The {@code ==} operator of SL is defined on all types. Therefore, we need a
  * {@link #equal(Object, Object) generic implementation} that can handle all possible types. But
  * since {@code ==} can only return {@code true} when the type of the left and right operand are the
  * same, the specializations already cover all possible cases that can return {@code true} and the
@@ -78,7 +78,7 @@
     }
 
     /**
-     * The {@link Generic} annotation informs that Truffle DSL that this method should be executed
+     * The {@link Generic} annotation informs the Truffle DSL that this method should be executed
      * when no {@link Specialization specialized method} matches. The operand types must be
      * {@link Object}.
      */
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -32,10 +32,10 @@
 /**
  * Reads a function argument. Arguments are passed in as a {@link SLArguments} object, which
  * encapsulates an {@link SLArguments#getFromFrame Object[] array}. Language-defined subclasses of
- * {@link Arguments} are the standard Truffle way to pass values between function.
+ * {@link Arguments} are the standard Truffle way to pass values between functions.
  * <p>
  * Arguments are not type-specialized. To ensure that repeated accesses within a method are
- * specialized and can, e.g., accessed without unboxing, all arguments are loaded into local
+ * specialized and can, e.g., be accessed without unboxing, all arguments are loaded into local
  * variables {@link SLNodeFactory#addFormalParameter in the method prologue}.
  */
 public class SLReadArgumentNode extends SLExpressionNode {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -33,7 +33,6 @@
  * variable changes its type, the frame access method throws an {@link FrameSlotTypeException},
  * which causes not rewriting. The rewriting code is generated by the Truffle DSL.
  */
-@PolymorphicLimit(1)
 @NodeField(name = "slot", type = FrameSlot.class)
 public abstract class SLReadLocalVariableNode extends SLExpressionNode {
 
@@ -53,13 +52,17 @@
         return frame.getBoolean(getSlot());
     }
 
-    @Specialization(rewriteOn = {FrameSlotTypeException.class})
+    @Specialization(order = 1, rewriteOn = {FrameSlotTypeException.class})
     protected Object readObject(VirtualFrame frame) throws FrameSlotTypeException {
         return frame.getObject(getSlot());
     }
 
-    @Generic
-    protected Object readGeneric(VirtualFrame frame) {
+    /**
+     * This is the generic case that always succeeds. Since we already have another specialization
+     * with the same signature above, we need to order them explicitly with the order attribute.
+     */
+    @Specialization(order = 2)
+    protected Object read(VirtualFrame frame) {
         return frame.getValue(getSlot());
     }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java	Wed Feb 05 08:02:15 2014 -0800
@@ -42,7 +42,7 @@
     protected abstract FrameSlot getSlot();
 
     /**
-     * Specialized method to write a primitive {@code long} value}. This is only possible if the
+     * Specialized method to write a primitive {@code long} value. This is only possible if the
      * local variable also has currently the type {@code long}, therefore a Truffle DSL
      * {@link #isLongKind() custom guard} is specified.
      */
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg	Wed Feb 05 08:02:15 2014 -0800
@@ -21,6 +21,12 @@
  * questions.
  */
 
+/*
+ * This is the grammar of SL that is used to automatically generate the Parser.java and Scanner.java
+ * files. You can download the parser generator Coco/R from http://ssw.jku.at/coco/. Then run
+ * "java -jar Coco.jar SimpleLanguage.atg"
+ */
+
 COMPILER SimpleLanguage
 
 CHARACTERS
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Wed Feb 05 15:50:36 2014 +0100
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Wed Feb 05 08:02:15 2014 -0800
@@ -39,9 +39,9 @@
  * context is used during {@link SLNodeFactory parsing} and by {@link SLBuiltinNode#getContext()
  * builtin functions}.
  * <p>
- * It would be an error to have two different context instances at the same. From a software
- * engineering point of view, it is better to pass around this encapsulated context object instead
- * of storing the data in static Java fields.
+ * It would be an error to have two different context instances during the execution of one script.
+ * However, if two separate scripts run in one Java VM at the same time, they have a different
+ * context. Therefore, the context is not a singleton.
  */
 public final class SLContext {
     private final SourceManager sourceManager;