# HG changeset patch # User Christian Wimmer # Date 1391616135 28800 # Node ID afd6fa5e82298b0a4c4a12ae02b542857ba6f419 # Parent 272a166a95746ecd345fd0653ce99e2829cfb44b SL: Feedback from reviewers diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl.test/tests/LoopCall.sl --- 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)); -} +} diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.output --- /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 diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl.test/tests/LoopInvalidate.sl --- /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)); +} diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl.test/tests/LoopPolymorphic.sl --- 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)); -} +} diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl.test/tests/LoopPrint.sl --- 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)); } diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl.test/tests/error/TypeError03.output --- /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 diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl.test/tests/error/TypeError03.sl --- /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; +} diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl.test/tests/error/TypeError04.output --- /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 diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl.test/tests/error/TypeError04.sl --- /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; +} diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java --- 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". + *

+ * 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) { diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLDefineFunctionBuiltin.java --- 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; } } diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLPrintlnBuiltin.java --- 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. + *

+ * 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); + } } diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/builtins/SLReadlnBuiltin.java --- 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()); } diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLBinaryNode.java --- 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 { diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java --- 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 { diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLCallNode.java --- 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); diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLBlockNode.java --- 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); } diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLFunctionBodyNode.java --- 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; diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java --- 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 diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLReturnNode.java --- 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; diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java --- 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 diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLDivNode.java --- 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; } diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java --- 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}. */ diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadArgumentNode.java --- 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. *

* 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 { diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java --- 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()); } } diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLWriteLocalVariableNode.java --- 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. */ diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/parser/SimpleLanguage.atg --- 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 diff -r 272a166a9574 -r afd6fa5e8229 graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java --- 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}. *

- * 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;