changeset 19292:906367e494ca

Truffle-DSL: fix invalid parameter order for executeWith with non-linear execution.
author Christian Humer <christian.humer@gmail.com>
date Wed, 11 Feb 2015 12:13:44 +0100
parents f4792a544170
children 21b9b9941775
files graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeChildData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeExecutionData.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ExecutableTypeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeMethodParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ShortCircuitParser.java
diffstat 7 files changed, 99 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java	Wed Feb 11 12:13:44 2015 +0100
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java	Wed Feb 11 12:13:44 2015 +0100
@@ -35,7 +35,8 @@
 import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs3Factory;
 import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs4Factory;
 import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.TestEvaluatedVarArgs5Factory;
-import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseDoubleEvaluatedNodeFactory;
+import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseDoubleEvaluated1NodeFactory;
+import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseDoubleEvaluated2NodeFactory;
 import com.oracle.truffle.api.dsl.test.ExecuteEvaluatedTestFactory.UseEvaluatedNodeFactory;
 import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode;
 import com.oracle.truffle.api.dsl.test.TypeSystemTest.ChildrenNode;
@@ -79,12 +80,12 @@
     }
 
     @Test
-    public void testDoubleEvaluated() {
+    public void testDoubleEvaluated1() {
         ArgumentNode arg0 = new ArgumentNode(0);
         ArgumentNode arg1 = new ArgumentNode(1);
-        CallTarget callTarget = TestHelper.createCallTarget(UseDoubleEvaluatedNodeFactory.create(arg0, arg1, DoubleEvaluatedNodeFactory.create(null, null)));
+        CallTarget callTarget = TestHelper.createCallTarget(UseDoubleEvaluated1NodeFactory.create(arg0, arg1, DoubleEvaluatedNodeFactory.create(null, null)));
 
-        Assert.assertEquals(85, callTarget.call(new Object[]{42, 43}));
+        Assert.assertEquals(42, callTarget.call(new Object[]{43, 1}));
         Assert.assertEquals(1, arg0.getInvocationCount());
         Assert.assertEquals(1, arg1.getInvocationCount());
     }
@@ -94,7 +95,7 @@
 
         @Specialization
         int doExecuteWith(int exp0, int exp1) {
-            return exp0 + exp1;
+            return exp0 - exp1;
         }
 
         public abstract Object executeEvaluated(VirtualFrame frame, Object exp0, Object exp1);
@@ -103,11 +104,32 @@
     }
 
     @NodeChildren({@NodeChild("exp0"), @NodeChild("exp1"), @NodeChild(value = "exp2", type = DoubleEvaluatedNode.class, executeWith = {"exp0", "exp1"})})
-    abstract static class UseDoubleEvaluatedNode extends ValueNode {
+    abstract static class UseDoubleEvaluated1Node extends ValueNode {
 
         @Specialization
         int call(int exp0, int exp1, int exp2) {
-            Assert.assertEquals(exp0 + exp1, exp2);
+            Assert.assertEquals(exp0 - exp1, exp2);
+            return exp2;
+        }
+    }
+
+    @Test
+    public void testDoubleEvaluated2() {
+        ArgumentNode arg0 = new ArgumentNode(0);
+        ArgumentNode arg1 = new ArgumentNode(1);
+        CallTarget callTarget = TestHelper.createCallTarget(UseDoubleEvaluated2NodeFactory.create(arg0, arg1, DoubleEvaluatedNodeFactory.create(null, null)));
+
+        Assert.assertEquals(42, callTarget.call(new Object[]{1, 43}));
+        Assert.assertEquals(1, arg0.getInvocationCount());
+        Assert.assertEquals(1, arg1.getInvocationCount());
+    }
+
+    @NodeChildren({@NodeChild("exp0"), @NodeChild("exp1"), @NodeChild(value = "exp2", type = DoubleEvaluatedNode.class, executeWith = {"exp1", "exp0"})})
+    abstract static class UseDoubleEvaluated2Node extends ValueNode {
+
+        @Specialization
+        int call(int exp0, int exp1, int exp2) {
+            Assert.assertEquals(exp1 - exp0, exp2);
             return exp2;
         }
     }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeChildData.java	Wed Feb 11 12:13:44 2015 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeChildData.java	Wed Feb 11 12:13:44 2015 +0100
@@ -52,7 +52,7 @@
     private final Element accessElement;
     private final Cardinality cardinality;
 
-    private List<NodeChildData> executeWith = Collections.emptyList();
+    private List<NodeExecutionData> executeWith = Collections.emptyList();
 
     private NodeData childNode;
 
@@ -66,11 +66,11 @@
         this.cardinality = cardinality;
     }
 
-    public List<NodeChildData> getExecuteWith() {
+    public List<NodeExecutionData> getExecuteWith() {
         return executeWith;
     }
 
-    public void setExecuteWith(List<NodeChildData> executeWith) {
+    public void setExecuteWith(List<NodeExecutionData> executeWith) {
         this.executeWith = executeWith;
     }
 
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeExecutionData.java	Wed Feb 11 12:13:44 2015 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeExecutionData.java	Wed Feb 11 12:13:44 2015 +0100
@@ -74,11 +74,11 @@
         return shortCircuit;
     }
 
-    public String getShortCircuitId() {
-        return createShortCircuitId(child, index);
+    public String getIndexedName() {
+        return createIndexedName(child, index);
     }
 
-    public static String createShortCircuitId(NodeChildData child, int varArgsIndex) {
+    public static String createIndexedName(NodeChildData child, int varArgsIndex) {
         String shortCircuitName = child.getName();
         if (child.getCardinality().isMany()) {
             shortCircuitName = shortCircuitName + "[" + varArgsIndex + "]";
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ExecutableTypeMethodParser.java	Wed Feb 11 12:13:44 2015 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ExecutableTypeMethodParser.java	Wed Feb 11 12:13:44 2015 +0100
@@ -36,9 +36,11 @@
 public class ExecutableTypeMethodParser extends NodeMethodParser<ExecutableTypeData> {
 
     private final List<TypeMirror> frameTypes;
+    private final NodeChildData child;
 
-    public ExecutableTypeMethodParser(ProcessorContext context, NodeData node, List<TypeMirror> frameTypes) {
+    public ExecutableTypeMethodParser(ProcessorContext context, NodeData node, NodeChildData child, List<TypeMirror> frameTypes) {
         super(context, node);
+        this.child = child;
         this.frameTypes = frameTypes;
         setParseNullOnError(false);
         getParser().setEmitErrors(false);
@@ -54,9 +56,19 @@
         TypeSystemData typeSystem = getNode().getTypeSystem();
         List<TypeMirror> allowedTypes = typeSystem.getPrimitiveTypeMirrors();
         Set<String> allowedIdentifiers = typeSystem.getTypeIdentifiers();
-        for (ParameterSpec originalSpec : requiredSpecs) {
-            spec.addRequired(new ParameterSpec(originalSpec, allowedTypes, allowedIdentifiers));
+
+        if (child != null) {
+            for (NodeExecutionData executeWith : child.getExecuteWith()) {
+                ParameterSpec parameter = spec.addRequired(new ParameterSpec(executeWith.getName(), allowedTypes, allowedIdentifiers));
+                parameter.setExecution(executeWith);
+                parameter.setSignature(true);
+            }
+        } else {
+            for (ParameterSpec originalSpec : requiredSpecs) {
+                spec.addRequired(new ParameterSpec(originalSpec, allowedTypes, allowedIdentifiers));
+            }
         }
+
         spec.setIgnoreAdditionalSpecifications(true);
         spec.setIgnoreAdditionalParameters(true);
         spec.setVariableRequiredParameters(true);
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeMethodParser.java	Wed Feb 11 12:13:44 2015 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeMethodParser.java	Wed Feb 11 12:13:44 2015 +0100
@@ -89,7 +89,7 @@
         }
 
         for (NodeExecutionData execution : getNode().getChildExecutions()) {
-            if (breakName != null && execution.getShortCircuitId().equals(breakName)) {
+            if (breakName != null && execution.getIndexedName().equals(breakName)) {
                 break;
             }
 
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java	Wed Feb 11 12:13:44 2015 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java	Wed Feb 11 12:13:44 2015 +0100
@@ -145,7 +145,7 @@
         node.getFields().addAll(parseFields(lookupTypes, members));
         node.getChildren().addAll(parseChildren(lookupTypes, members));
         node.getChildExecutions().addAll(parseExecutions(node.getChildren(), members));
-        node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, context.getFrameTypes()).parse(members)));
+        node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, null, context.getFrameTypes()).parse(members)));
 
         initializeExecutableTypes(node);
         initializeImportGuards(node, lookupTypes, members);
@@ -402,46 +402,6 @@
             }
         }
 
-        for (NodeChildData child : filteredChildren) {
-            List<String> executeWithStrings = ElementUtils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith");
-            AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(child.getMessageAnnotation(), "executeWith");
-            List<NodeChildData> executeWith = new ArrayList<>();
-            for (String executeWithString : executeWithStrings) {
-
-                if (child.getName().equals(executeWithString)) {
-                    child.addError(executeWithValue, "The child node '%s' cannot be executed with itself.", executeWithString);
-                    continue;
-                }
-
-                NodeChildData found = null;
-                boolean before = true;
-                for (NodeChildData resolveChild : filteredChildren) {
-                    if (resolveChild == child) {
-                        before = false;
-                        continue;
-                    }
-                    if (resolveChild.getName().equals(executeWithString)) {
-                        found = resolveChild;
-                        break;
-                    }
-                }
-
-                if (found == null) {
-                    child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString);
-                    continue;
-                } else if (!before) {
-                    child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString,
-                                    executeWithString);
-                    continue;
-                }
-                executeWith.add(found);
-            }
-            child.setExecuteWith(executeWith);
-            if (child.getNodeData() == null) {
-                continue;
-            }
-        }
-
         return filteredChildren;
     }
 
@@ -504,7 +464,7 @@
                 }
                 if (!skipShortCircuit) {
                     NodeChildData child = children.get(childIndex);
-                    if (shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, currentArgumentIndex - childIndex))) {
+                    if (shortCircuits.contains(NodeExecutionData.createIndexedName(child, currentArgumentIndex - childIndex))) {
                         skipShortCircuit = true;
                         continue;
                     }
@@ -531,7 +491,7 @@
             }
             int varArgsIndex = varArg ? Math.abs(childIndex - i) : -1;
             NodeChildData child = children.get(childIndex);
-            boolean shortCircuit = shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, varArgsIndex));
+            boolean shortCircuit = shortCircuits.contains(NodeExecutionData.createIndexedName(child, varArgsIndex));
             executions.add(new NodeExecutionData(child, varArgsIndex, shortCircuit));
         }
         return executions;
@@ -638,9 +598,11 @@
     }
 
     private void initializeChildren(NodeData node) {
+        initializeExecuteWith(node);
+
         for (NodeChildData child : node.getChildren()) {
             TypeMirror nodeType = child.getNodeType();
-            NodeData fieldNodeData = parseChildNodeData(node, ElementUtils.fromTypeMirror(nodeType));
+            NodeData fieldNodeData = parseChildNodeData(node, child, ElementUtils.fromTypeMirror(nodeType));
 
             child.setNode(fieldNodeData);
             if (fieldNodeData == null || fieldNodeData.hasErrors()) {
@@ -660,7 +622,44 @@
         }
     }
 
-    private NodeData parseChildNodeData(NodeData parentNode, TypeElement originalTemplateType) {
+    private static void initializeExecuteWith(NodeData node) {
+        for (NodeChildData child : node.getChildren()) {
+            List<String> executeWithStrings = ElementUtils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith");
+            AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(child.getMessageAnnotation(), "executeWith");
+            List<NodeExecutionData> executeWith = new ArrayList<>();
+            for (String executeWithString : executeWithStrings) {
+                if (child.getName().equals(executeWithString)) {
+                    child.addError(executeWithValue, "The child node '%s' cannot be executed with itself.", executeWithString);
+                    continue;
+                }
+                NodeExecutionData found = null;
+                boolean before = true;
+                for (NodeExecutionData resolveChild : node.getChildExecutions()) {
+                    if (resolveChild.getChild() == child) {
+                        before = false;
+                        continue;
+                    }
+                    if (resolveChild.getIndexedName().equals(executeWithString)) {
+                        found = resolveChild;
+                        break;
+                    }
+                }
+
+                if (found == null) {
+                    child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The child node was not found.", child.getName(), executeWithString);
+                    continue;
+                } else if (!before) {
+                    child.addError(executeWithValue, "The child node '%s' cannot be executed with '%s'. The node %s is executed after the current node.", child.getName(), executeWithString,
+                                    executeWithString);
+                    continue;
+                }
+                executeWith.add(found);
+            }
+            child.setExecuteWith(executeWith);
+        }
+    }
+
+    private NodeData parseChildNodeData(NodeData parentNode, NodeChildData child, TypeElement originalTemplateType) {
         TypeElement templateType = ElementUtils.fromTypeMirror(context.reloadTypeElement(originalTemplateType));
 
         if (ElementUtils.findAnnotationMirror(processingEnv, originalTemplateType, GeneratedBy.class) != null) {
@@ -680,7 +679,7 @@
         if (node.hasErrors()) {
             return node;
         }
-        node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, createAllowedChildFrameTypes(parentNode)).parse(members)));
+        node.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, node, child, createAllowedChildFrameTypes(parentNode)).parse(members)));
         node.setFrameType(parentNode.getFrameType());
         return node;
     }
@@ -1288,7 +1287,7 @@
                 continue;
             }
             shortCircuitExecutions.add(execution);
-            String valueName = execution.getShortCircuitId();
+            String valueName = execution.getIndexedName();
             List<ShortCircuitData> availableCircuits = groupedShortCircuits.get(valueName);
 
             if (availableCircuits == null || availableCircuits.isEmpty()) {
@@ -1344,7 +1343,7 @@
             List<ShortCircuitData> assignedShortCuts = new ArrayList<>(shortCircuitExecutions.size());
 
             for (NodeExecutionData shortCircuit : shortCircuitExecutions) {
-                List<ShortCircuitData> availableShortCuts = groupedShortCircuits.get(shortCircuit.getShortCircuitId());
+                List<ShortCircuitData> availableShortCuts = groupedShortCircuits.get(shortCircuit.getIndexedName());
 
                 ShortCircuitData genericShortCircuit = null;
                 ShortCircuitData compatibleShortCircuit = null;
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ShortCircuitParser.java	Wed Feb 11 12:13:44 2015 +0100
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ShortCircuitParser.java	Wed Feb 11 12:13:44 2015 +0100
@@ -42,7 +42,7 @@
         shortCircuitValues = new HashSet<>();
         for (NodeExecutionData execution : node.getChildExecutions()) {
             if (execution.isShortCircuit()) {
-                shortCircuitValues.add(execution.getShortCircuitId());
+                shortCircuitValues.add(execution.getIndexedName());
             }
         }
     }