changeset 13863:88026f1d51e4

Merge.
author Christian Humer <christian.humer@gmail.com>
date Mon, 03 Feb 2014 21:01:26 +0100
parents f9b934e1e172 (diff) 1e01e2644a5d (current diff)
children 5365f8d35b06
files
diffstat 8 files changed, 153 insertions(+), 63 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/UnsupportedSpecializationTest.java	Mon Feb 03 10:43:11 2014 -0800
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/UnsupportedSpecializationTest.java	Mon Feb 03 21:01:26 2014 +0100
@@ -22,18 +22,22 @@
  */
 package com.oracle.truffle.api.dsl.test;
 
+import java.util.*;
+
 import org.junit.*;
 
 import com.oracle.truffle.api.dsl.*;
 import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
 import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
-import com.oracle.truffle.api.dsl.test.UnsupportedSpecializationTestFactory.Undefined1Factory;
+import com.oracle.truffle.api.dsl.test.UnsupportedSpecializationTestFactory.Unsupported1Factory;
+import com.oracle.truffle.api.dsl.test.UnsupportedSpecializationTestFactory.Unsupported2Factory;
+import com.oracle.truffle.api.nodes.*;
 
 public class UnsupportedSpecializationTest {
 
     @Test
-    public void testUndefined1() {
-        TestRootNode<Undefined1> root = TestHelper.createRoot(Undefined1Factory.getInstance());
+    public void testUnsupported1() {
+        TestRootNode<Unsupported1> root = TestHelper.createRoot(Unsupported1Factory.getInstance());
         try {
             TestHelper.executeWith(root, "");
             Assert.fail();
@@ -41,12 +45,13 @@
             Assert.assertNotNull(e.getSuppliedValues());
             Assert.assertEquals(1, e.getSuppliedValues().length);
             Assert.assertEquals("", e.getSuppliedValues()[0]);
+            Assert.assertSame(root.getNode().getChildren().iterator().next(), e.getSuppliedNodes()[0]);
             Assert.assertEquals(root.getNode(), e.getNode());
         }
     }
 
     @NodeChild("a")
-    abstract static class Undefined1 extends ValueNode {
+    abstract static class Unsupported1 extends ValueNode {
 
         @Specialization
         public int doInteger(@SuppressWarnings("unused") int a) {
@@ -54,5 +59,41 @@
         }
     }
 
-    // TODO more tests required
+    @Test
+    public void testUnsupported2() {
+        TestRootNode<Unsupported2> root = TestHelper.createRoot(Unsupported2Factory.getInstance());
+        try {
+            TestHelper.executeWith(root, "", 1);
+            Assert.fail();
+        } catch (UnsupportedSpecializationException e) {
+            Assert.assertNotNull(e.getSuppliedValues());
+            Assert.assertNotNull(e.getSuppliedNodes());
+            Assert.assertEquals(3, e.getSuppliedValues().length);
+            Assert.assertEquals(3, e.getSuppliedNodes().length);
+            Assert.assertEquals("", e.getSuppliedValues()[0]);
+            Assert.assertEquals(false, e.getSuppliedValues()[1]);
+            Assert.assertEquals(null, e.getSuppliedValues()[2]);
+            List<Node> children = NodeUtil.findNodeChildren(root.getNode());
+            Assert.assertSame(children.get(0), e.getSuppliedNodes()[0]);
+            Assert.assertNull(e.getSuppliedNodes()[1]);
+            Assert.assertSame(children.get(1), e.getSuppliedNodes()[2]);
+            Assert.assertEquals(root.getNode(), e.getNode());
+        }
+    }
+
+    @SuppressWarnings("unused")
+    @NodeChildren({@NodeChild("a"), @NodeChild("b")})
+    abstract static class Unsupported2 extends ValueNode {
+
+        @ShortCircuit("b")
+        public boolean needsB(Object a) {
+            return false;
+        }
+
+        @Specialization
+        public int doInteger(int a, boolean hasB, int b) {
+            throw new AssertionError();
+        }
+    }
+
 }
--- a/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/UnsupportedSpecializationException.java	Mon Feb 03 10:43:11 2014 -0800
+++ b/graal/com.oracle.truffle.api.dsl/src/com/oracle/truffle/api/dsl/UnsupportedSpecializationException.java	Mon Feb 03 21:01:26 2014 +0100
@@ -37,11 +37,17 @@
     private static final long serialVersionUID = -2122892028296836269L;
 
     private final Node node;
+    private final Node[] suppliedNodes;
     private final Object[] suppliedValues;
 
-    public UnsupportedSpecializationException(Node node, Object... suppliedValues) {
+    public UnsupportedSpecializationException(Node node, Node[] suppliedNodes, Object... suppliedValues) {
         super("Unexpected values provided for " + node + ": " + Arrays.toString(suppliedValues));
+        Objects.requireNonNull(suppliedNodes, "The suppliedNodes parameter must not be null.");
+        if (suppliedNodes.length != suppliedValues.length) {
+            throw new IllegalArgumentException("The length of suppliedNodes must match the length of suppliedValues.");
+        }
         this.node = node;
+        this.suppliedNodes = suppliedNodes;
         this.suppliedValues = suppliedValues;
     }
 
@@ -53,7 +59,19 @@
     }
 
     /**
-     * Returns the dynamic values that were supplied to the node.
+     * Returns the children of the {@link Node} returned by {@link #getNode()} which produced the
+     * values returned by {@link #getSuppliedValues()}. The array returned by
+     * {@link #getSuppliedNodes()} has the same length as the array returned by
+     * {@link #getSuppliedValues()}. Never returns null.
+     */
+    public Node[] getSuppliedNodes() {
+        return suppliedNodes;
+    }
+
+    /**
+     * Returns the dynamic values that were supplied to the node.The array returned by
+     * {@link #getSuppliedNodes()} has the same length as the array returned by
+     * {@link #getSuppliedValues()}. Never returns null.
      */
     public Object[] getSuppliedValues() {
         return suppliedValues;
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java	Mon Feb 03 10:43:11 2014 -0800
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java	Mon Feb 03 21:01:26 2014 +0100
@@ -43,8 +43,8 @@
 
     public static final String OPTION_DETAILED_REWRITE_REASONS = "DetailedRewriteReasons";
 
-    private final TypeMirror node;
-    private final TypeMirror nodeArray;
+    private final DeclaredType node;
+    private final ArrayType nodeArray;
     private final TypeMirror unexpectedValueException;
     private final TypeMirror frame;
     private final TypeMirror assumption;
@@ -131,11 +131,11 @@
         return compilerDirectives;
     }
 
-    public TypeMirror getNode() {
+    public DeclaredType getNode() {
         return node;
     }
 
-    public TypeMirror getNodeArray() {
+    public ArrayType getNodeArray() {
         return nodeArray;
     }
 
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Mon Feb 03 10:43:11 2014 -0800
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Mon Feb 03 21:01:26 2014 +0100
@@ -99,6 +99,22 @@
         return param.getLocalName();
     }
 
+    private static CodeTree createAccessChild(NodeExecutionData targetExecution) {
+        CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
+        Element accessElement = targetExecution.getChild().getAccessElement();
+        if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) {
+            builder.string("this.").string(targetExecution.getChild().getName());
+        } else if (accessElement.getKind() == ElementKind.FIELD) {
+            builder.string("this.").string(accessElement.getSimpleName().toString());
+        } else {
+            throw new AssertionError();
+        }
+        if (targetExecution.isIndexed()) {
+            builder.string("[" + targetExecution.getIndex() + "]");
+        }
+        return builder.getRoot();
+    }
+
     private static String castValueName(ActualParameter parameter) {
         return valueName(parameter) + "Cast";
     }
@@ -155,18 +171,14 @@
     }
 
     private String valueName(ActualParameter sourceParameter, ActualParameter targetParameter) {
-        if (sourceParameter != null) {
-            if (!sourceParameter.getSpecification().isSignature()) {
-                return valueName(targetParameter);
-            } else if (sourceParameter.getTypeSystemType() != null && targetParameter.getTypeSystemType() != null) {
-                if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), targetParameter.getTypeSystemType())) {
-                    return castValueName(targetParameter);
-                }
+        if (!sourceParameter.getSpecification().isSignature()) {
+            return valueName(targetParameter);
+        } else if (sourceParameter.getTypeSystemType() != null && targetParameter.getTypeSystemType() != null) {
+            if (sourceParameter.getTypeSystemType().needsCastTo(getContext(), targetParameter.getTypeSystemType())) {
+                return castValueName(targetParameter);
             }
-            return valueName(targetParameter);
-        } else {
-            return valueName(targetParameter);
         }
+        return valueName(targetParameter);
     }
 
     private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, CodeTree target, TemplateMethod sourceMethod, TemplateMethod targetMethod, String unexpectedValueName,
@@ -331,9 +343,35 @@
     }
 
     protected void emitEncounteredSynthetic(CodeTreeBuilder builder, TemplateMethod current) {
+        CodeTreeBuilder nodes = builder.create();
+        CodeTreeBuilder arguments = builder.create();
+        nodes.startCommaGroup();
+        arguments.startCommaGroup();
+        boolean empty = true;
+        for (ActualParameter parameter : current.getParameters()) {
+            NodeExecutionData executionData = parameter.getSpecification().getExecution();
+            if (executionData != null) {
+                if (executionData.isShortCircuit()) {
+                    nodes.nullLiteral();
+                    arguments.string(valueName(parameter.getPreviousParameter()));
+                }
+                nodes.tree(createAccessChild(executionData));
+                arguments.string(valueName(parameter));
+                empty = false;
+            }
+        }
+        nodes.end();
+        arguments.end();
+
         builder.startThrow().startNew(getContext().getType(UnsupportedSpecializationException.class));
         builder.string("this");
-        addInternalValueParameterNames(builder, current, current, null, false, null);
+        builder.startNewArray(getContext().getTruffleTypes().getNodeArray(), null);
+
+        builder.tree(nodes.getRoot());
+        builder.end();
+        if (!empty) {
+            builder.tree(arguments.getRoot());
+        }
         builder.end().end();
     }
 
@@ -965,16 +1003,12 @@
             for (ActualParameter param : getModel().getSignatureParameters()) {
                 NodeExecutionData execution = param.getSpecification().getExecution();
 
-                CodeTreeBuilder access = builder.create();
-                access.string("this.").string(execution.getChild().getName());
-                if (execution.isIndexed()) {
-                    access.string("[").string(String.valueOf(execution.getIndex())).string("]");
-                }
+                CodeTree access = createAccessChild(execution);
 
                 String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName());
                 oldBuilder.declaration(execution.getChild().getNodeData().getNodeType(), oldName, access);
-                nullBuilder.startStatement().tree(access.getRoot()).string(" = null").end();
-                resetBuilder.startStatement().tree(access.getRoot()).string(" = ").string(oldName).end();
+                nullBuilder.startStatement().tree(access).string(" = null").end();
+                resetBuilder.startStatement().tree(access).string(" = ").string(oldName).end();
             }
 
             builder.tree(oldBuilder.getRoot());
@@ -2274,7 +2308,7 @@
         private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, ActualParameter unexpectedParameter) {
             CodeTreeBuilder builder = new CodeTreeBuilder(parent);
             if (targetExecution != null) {
-                builder.tree(createAccessChild(builder, targetExecution));
+                builder.tree(createAccessChild(targetExecution));
                 builder.string(".");
             }
 
@@ -2328,22 +2362,6 @@
             return builder.getRoot();
         }
 
-        private CodeTree createAccessChild(CodeTreeBuilder parent, NodeExecutionData targetExecution) throws AssertionError {
-            CodeTreeBuilder builder = parent.create();
-            Element accessElement = targetExecution.getChild().getAccessElement();
-            if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) {
-                builder.string("this.").string(targetExecution.getChild().getName());
-            } else if (accessElement.getKind() == ElementKind.FIELD) {
-                builder.string("this.").string(accessElement.getSimpleName().toString());
-            } else {
-                throw new AssertionError();
-            }
-            if (targetExecution.isIndexed()) {
-                builder.string("[" + targetExecution.getIndex() + "]");
-            }
-            return builder.getRoot();
-        }
-
         private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) {
             NodeExecutionData execution = parameter.getSpecification().getExecution();
             if (execution == null || !execution.isShortCircuit()) {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java	Mon Feb 03 10:43:11 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java	Mon Feb 03 21:01:26 2014 +0100
@@ -154,8 +154,10 @@
 
         /* Change to true if you want to see the AST on the console. */
         boolean printASTToLog = false;
+        /* Change to dump the AST to IGV over the network. */
+        boolean dumpASTToIGV = false;
 
-        printScript("before execution", context, logOutput, printASTToLog);
+        printScript("before execution", context, logOutput, printASTToLog, dumpASTToIGV);
         try {
             for (int i = 0; i < repeats; i++) {
                 long start = System.nanoTime();
@@ -176,7 +178,7 @@
             }
 
         } finally {
-            printScript("after execution", context, logOutput, printASTToLog);
+            printScript("after execution", context, logOutput, printASTToLog, dumpASTToIGV);
         }
     }
 
@@ -184,21 +186,27 @@
      * 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.
      */
-    private static void printScript(String groupName, SLContext context, PrintStream logOutput, boolean printASTToLog) {
-        GraphPrintVisitor graphPrinter = new GraphPrintVisitor();
-        graphPrinter.beginGroup(groupName);
-        for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
-            RootCallTarget callTarget = function.getCallTarget();
-            if (callTarget != null) {
-                graphPrinter.beginGraph(function.toString()).visit(callTarget.getRootNode());
-
-                if (logOutput != null && printASTToLog) {
+    private static void printScript(String groupName, SLContext context, PrintStream logOutput, boolean printASTToLog, boolean dumpASTToIGV) {
+        if (dumpASTToIGV) {
+            GraphPrintVisitor graphPrinter = new GraphPrintVisitor();
+            graphPrinter.beginGroup(groupName);
+            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
+                RootCallTarget callTarget = function.getCallTarget();
+                if (callTarget != null) {
+                    graphPrinter.beginGraph(function.toString()).visit(callTarget.getRootNode());
+                }
+            }
+            graphPrinter.printToNetwork(true);
+        }
+        if (printASTToLog && logOutput != null) {
+            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
+                RootCallTarget callTarget = function.getCallTarget();
+                if (callTarget != null) {
                     logOutput.println("=== " + function);
                     NodeUtil.printTree(logOutput, callTarget.getRootNode());
                 }
             }
         }
-        graphPrinter.printToNetwork(true);
     }
 
     /**
@@ -223,8 +231,10 @@
         result.append(" not defined for");
 
         String sep = " ";
-        for (Object value : ex.getSuppliedValues()) {
-            if (value != null) {
+        for (int i = 0; i < ex.getSuppliedValues().length; i++) {
+            Object value = ex.getSuppliedValues()[i];
+            Node node = ex.getSuppliedNodes()[i];
+            if (node != null) {
                 result.append(sep);
                 sep = ", ";
 
@@ -238,6 +248,9 @@
                     result.append("Function ").append(value);
                 } else if (value == SLNull.SINGLETON) {
                     result.append("NULL");
+                } else if (value == null) {
+                    // value is not evaluated because of short circuit evaluation
+                    result.append("ANY");
                 } else {
                     result.append(value);
                 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLCallNode.java	Mon Feb 03 10:43:11 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/call/SLCallNode.java	Mon Feb 03 21:01:26 2014 +0100
@@ -79,7 +79,7 @@
              * program. We report it with the same exception that Truffle DSL generated nodes use to
              * report type errors.
              */
-            throw new UnsupportedSpecializationException(this, ex.getResult());
+            throw new UnsupportedSpecializationException(this, new Node[]{functionNode}, ex.getResult());
         }
     }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java	Mon Feb 03 10:43:11 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLIfNode.java	Mon Feb 03 21:01:26 2014 +0100
@@ -92,7 +92,7 @@
              * program. We report it with the same exception that Truffle DSL generated nodes use to
              * report type errors.
              */
-            throw new UnsupportedSpecializationException(this, ex.getResult());
+            throw new UnsupportedSpecializationException(this, new Node[]{conditionNode}, ex.getResult());
         }
     }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java	Mon Feb 03 10:43:11 2014 -0800
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/controlflow/SLWhileNode.java	Mon Feb 03 21:01:26 2014 +0100
@@ -107,7 +107,7 @@
              * program. We report it with the same exception that Truffle DSL generated nodes use to
              * report type errors.
              */
-            throw new UnsupportedSpecializationException(this, ex.getResult());
+            throw new UnsupportedSpecializationException(this, new Node[]{conditionNode}, ex.getResult());
         }
     }
 }