# HG changeset patch # User Christian Humer # Date 1423653224 -3600 # Node ID 906367e494ca2b2bfb704bcb7faef39b14215128 # Parent f4792a54417091e1aaebb4c2bd3e63d93926276b Truffle-DSL: fix invalid parameter order for executeWith with non-linear execution. diff -r f4792a544170 -r 906367e494ca graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ExecuteEvaluatedTest.java --- 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; } } diff -r f4792a544170 -r 906367e494ca graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeChildData.java --- 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 executeWith = Collections.emptyList(); + private List executeWith = Collections.emptyList(); private NodeData childNode; @@ -66,11 +66,11 @@ this.cardinality = cardinality; } - public List getExecuteWith() { + public List getExecuteWith() { return executeWith; } - public void setExecuteWith(List executeWith) { + public void setExecuteWith(List executeWith) { this.executeWith = executeWith; } diff -r f4792a544170 -r 906367e494ca graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/model/NodeExecutionData.java --- 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 + "]"; diff -r f4792a544170 -r 906367e494ca graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ExecutableTypeMethodParser.java --- 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 { private final List frameTypes; + private final NodeChildData child; - public ExecutableTypeMethodParser(ProcessorContext context, NodeData node, List frameTypes) { + public ExecutableTypeMethodParser(ProcessorContext context, NodeData node, NodeChildData child, List frameTypes) { super(context, node); + this.child = child; this.frameTypes = frameTypes; setParseNullOnError(false); getParser().setEmitErrors(false); @@ -54,9 +56,19 @@ TypeSystemData typeSystem = getNode().getTypeSystem(); List allowedTypes = typeSystem.getPrimitiveTypeMirrors(); Set 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); diff -r f4792a544170 -r 906367e494ca graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeMethodParser.java --- 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; } diff -r f4792a544170 -r 906367e494ca graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java --- 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 executeWithStrings = ElementUtils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith"); - AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(child.getMessageAnnotation(), "executeWith"); - List 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 executeWithStrings = ElementUtils.getAnnotationValueList(String.class, child.getMessageAnnotation(), "executeWith"); + AnnotationValue executeWithValue = ElementUtils.getAnnotationValue(child.getMessageAnnotation(), "executeWith"); + List 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 availableCircuits = groupedShortCircuits.get(valueName); if (availableCircuits == null || availableCircuits.isEmpty()) { @@ -1344,7 +1343,7 @@ List assignedShortCuts = new ArrayList<>(shortCircuitExecutions.size()); for (NodeExecutionData shortCircuit : shortCircuitExecutions) { - List availableShortCuts = groupedShortCircuits.get(shortCircuit.getShortCircuitId()); + List availableShortCuts = groupedShortCircuits.get(shortCircuit.getIndexedName()); ShortCircuitData genericShortCircuit = null; ShortCircuitData compatibleShortCircuit = null; diff -r f4792a544170 -r 906367e494ca graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/ShortCircuitParser.java --- 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()); } } }