# HG changeset patch # User Christian Humer # Date 1389093767 -3600 # Node ID 25ecb47a6d0ea683cd69a1cfa9b989eb4ced255e # Parent 37ec2cabf3976c547aab5c5ee67e9e21e7e4e521 Truffle-DSL: Added support for references to child arrays in @ShortCircuit; Introduced new layer NodeExecutionData to the implementation model which is in between NodeChildData and the actual parameters.. diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ShortCircuitTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/ShortCircuitTest.java Tue Jan 07 12:22:47 2014 +0100 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.api.dsl.test; + +import static org.junit.Assert.*; + +import org.junit.*; + +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.DoubleChildNodeFactory; +import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.SingleChildNodeFactory; +import com.oracle.truffle.api.dsl.test.ShortCircuitTestFactory.VarArgsNodeFactory; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ArgumentNode; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestArguments; +import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode; + +public class ShortCircuitTest { + + @Test + public void testSingleChild1() { + ArgumentNode arg0 = new ArgumentNode(0); + CallTarget callTarget = TestHelper.createCallTarget(SingleChildNodeFactory.create(arg0)); + SingleChildNode.needsChild = true; + assertEquals(42, callTarget.call(new TestArguments(42))); + assertEquals(1, arg0.getInvocationCount()); + } + + @Test + public void testSingleChild2() { + ArgumentNode arg0 = new ArgumentNode(0); + CallTarget callTarget = TestHelper.createCallTarget(SingleChildNodeFactory.create(arg0)); + SingleChildNode.needsChild = false; + assertEquals(0, callTarget.call(new TestArguments(42))); + assertEquals(0, arg0.getInvocationCount()); + } + + @NodeChild("child0") + abstract static class SingleChildNode extends ValueNode { + + static boolean needsChild; + + @ShortCircuit("child0") + boolean needsChild0() { + return needsChild; + } + + @Specialization + int doIt(boolean hasChild0, int child0) { + assert hasChild0 == needsChild0(); + return child0; + } + + } + + @Test + public void testDoubleChild1() { + ArgumentNode arg0 = new ArgumentNode(0); + ArgumentNode arg1 = new ArgumentNode(1); + CallTarget callTarget = TestHelper.createCallTarget(DoubleChildNodeFactory.create(arg0, arg1)); + assertEquals(42, callTarget.call(new TestArguments(41, 42))); + assertEquals(1, arg1.getInvocationCount()); + } + + @Test + public void testDoubleChild2() { + ArgumentNode arg0 = new ArgumentNode(0); + ArgumentNode arg1 = new ArgumentNode(1); + CallTarget callTarget = TestHelper.createCallTarget(DoubleChildNodeFactory.create(arg0, arg1)); + assertEquals(0, callTarget.call(new TestArguments(42, 42))); + assertEquals(0, arg1.getInvocationCount()); + } + + @NodeChildren({@NodeChild("child0"), @NodeChild("child1")}) + @SuppressWarnings("unused") + abstract static class DoubleChildNode extends ValueNode { + + @ShortCircuit("child1") + boolean needsChild1(Object leftValue) { + return leftValue.equals(41); + } + + @Specialization + int doIt(int child0, boolean hasChild1, int child1) { + return child1; + } + + } + + @Test + public void testVarArgs1() { + ArgumentNode arg0 = new ArgumentNode(0); + ArgumentNode arg1 = new ArgumentNode(1); + CallTarget callTarget = TestHelper.createCallTarget(VarArgsNodeFactory.create(new ValueNode[]{arg0, arg1})); + assertEquals(42, callTarget.call(new TestArguments(41, 42))); + assertEquals(1, arg1.getInvocationCount()); + } + + @Test + public void testVarArgs2() { + ArgumentNode arg0 = new ArgumentNode(0); + ArgumentNode arg1 = new ArgumentNode(1); + CallTarget callTarget = TestHelper.createCallTarget(VarArgsNodeFactory.create(new ValueNode[]{arg0, arg1})); + assertEquals(0, callTarget.call(new TestArguments(42, 42))); + assertEquals(0, arg1.getInvocationCount()); + } + + @NodeChild(value = "children", type = ValueNode[].class) + abstract static class VarArgsNode extends ValueNode { + + @ShortCircuit("children[1]") + boolean needsChild1(Object leftValue) { + return leftValue.equals(41); + } + + @Specialization + @SuppressWarnings("unused") + int doIt(int child0, boolean hasChild1, int child1) { + return child1; + } + + } + +} diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/CreateCastParser.java Tue Jan 07 12:22:47 2014 +0100 @@ -46,17 +46,21 @@ @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { List childNames = Utils.getAnnotationValueList(String.class, mirror, "value"); - TypeMirror baseType = getContext().getTruffleTypes().getNode(); + NodeChildData foundChild = null; for (String childName : childNames) { - NodeChildData child = getNode().findChild(childName); - if (child != null) { - baseType = child.getOriginalType(); + foundChild = getNode().findChild(childName); + if (foundChild != null) { break; } } + TypeMirror baseType = getContext().getTruffleTypes().getNode(); + if (foundChild != null) { + baseType = foundChild.getOriginalType(); + } + MethodSpec spec = new MethodSpec(new InheritsParameterSpec(getContext(), "child", baseType)); addDefaultFieldMethodSpec(spec); - spec.addRequired(new ParameterSpec("castedChild", baseType)).setSignature(true); + spec.addRequired(new ParameterSpec("castedChild", baseType)); return spec; } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ExecutableTypeMethodParser.java Tue Jan 07 12:22:47 2014 +0100 @@ -29,7 +29,6 @@ import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.node.NodeChildData.*; import com.oracle.truffle.dsl.processor.template.*; import com.oracle.truffle.dsl.processor.typesystem.*; @@ -52,13 +51,11 @@ for (ParameterSpec originalSpec : requiredSpecs) { spec.addRequired(new ParameterSpec(originalSpec, allowedTypes)); } - - spec.setVariableRequiredArguments(true); - ParameterSpec other = new ParameterSpec("other", allowedTypes); - other.setCardinality(Cardinality.MANY); - other.setSignature(true); - other.setIndexed(true); - spec.addRequired(other); + spec.setIgnoreAdditionalSpecifications(true); + spec.setIgnoreAdditionalParameters(true); + spec.setVariableRequiredParameters(true); + // varargs + spec.addRequired(new ParameterSpec("other", allowedTypes)); return spec; } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/GenericParser.java Tue Jan 07 12:22:47 2014 +0100 @@ -44,23 +44,18 @@ } @Override - protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, int evaluatedCount) { - List execTypes = nodeData.findGenericExecutableTypes(getContext(), evaluatedCount); + protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) { + List execTypes = execution.getChild().getNodeData().findGenericExecutableTypes(getContext(), execution.getChild().getExecuteWith().size()); List types = new ArrayList<>(); for (ExecutableTypeData type : execTypes) { types.add(type.getType().getPrimitiveType()); } - ParameterSpec spec = new ParameterSpec(valueName, types); - spec.setSignature(true); + ParameterSpec spec = new ParameterSpec(execution.getName(), types); + spec.setExecution(execution); return spec; } @Override - protected ParameterSpec createReturnParameterSpec() { - return super.createValueParameterSpec("returnValue", getNode(), 0); - } - - @Override public SpecializationData create(TemplateMethod method, boolean invalid) { SpecializationData data = new SpecializationData(method, true, false, false); return data; diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeChildData.java Tue Jan 07 12:22:47 2014 +0100 @@ -45,10 +45,6 @@ } } - public enum ExecutionKind { - DEFAULT, SHORT_CIRCUIT - } - private final NodeData parent; private final Element sourceElement; private final AnnotationMirror sourceAnnotationMirror; @@ -59,14 +55,13 @@ private final Element accessElement; private final Cardinality cardinality; - private final ExecutionKind executionKind; private List executeWith = Collections.emptyList(); private NodeData nodeData; public NodeChildData(NodeData parent, Element sourceElement, AnnotationMirror sourceMirror, String name, TypeMirror nodeType, TypeMirror originalNodeType, Element accessElement, - Cardinality cardinality, ExecutionKind executionKind) { + Cardinality cardinality) { this.parent = parent; this.sourceElement = sourceElement; this.sourceAnnotationMirror = sourceMirror; @@ -75,7 +70,6 @@ this.originalType = originalNodeType; this.accessElement = accessElement; this.cardinality = cardinality; - this.executionKind = executionKind; } public List getExecuteWith() { @@ -92,18 +86,12 @@ } boolean used = false; - SpecializationData generic = parent.getGenericSpecialization(); - for (ActualParameter param : generic.getParameters()) { - if (!param.getSpecification().isSignature()) { - continue; - } - NodeChildData child = parent.findChild(param.getSpecification().getName()); - if (child == this) { + for (NodeExecutionData execution : parent.getChildExecutions()) { + if (execution.getChild() == this) { used = true; break; } } - if (!used) { return false; } @@ -145,10 +133,6 @@ return sourceAnnotationMirror; } - public boolean isShortCircuit() { - return executionKind == ExecutionKind.SHORT_CIRCUIT; - } - void setNode(NodeData nodeData) { this.nodeData = nodeData; if (nodeData != null) { @@ -168,10 +152,6 @@ return cardinality; } - public ExecutionKind getExecutionKind() { - return executionKind; - } - public NodeData getNodeData() { return nodeData; } @@ -182,7 +162,7 @@ @Override public String toString() { - return "NodeFieldData[name=" + getName() + ", kind=" + cardinality + ", execution=" + executionKind + ", node=" + getNodeData() + "]"; + return "NodeFieldData[name=" + getName() + ", kind=" + cardinality + ", node=" + getNodeData() + "]"; } } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Tue Jan 07 12:22:47 2014 +0100 @@ -37,7 +37,6 @@ import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.ast.*; import com.oracle.truffle.dsl.processor.node.NodeChildData.Cardinality; -import com.oracle.truffle.dsl.processor.node.NodeChildData.ExecutionKind; import com.oracle.truffle.dsl.processor.node.SpecializationGroup.TypeGuard; import com.oracle.truffle.dsl.processor.template.*; import com.oracle.truffle.dsl.processor.typesystem.*; @@ -632,21 +631,9 @@ List signatureTypes = new ArrayList<>(); assert !node.getSpecializations().isEmpty(); SpecializationData data = node.getSpecializations().get(0); - for (ActualParameter parameter : data.getParameters()) { - ParameterSpec spec = parameter.getSpecification(); - NodeChildData field = node.findChild(spec.getName()); - if (field == null) { - continue; - } - - TypeMirror type; - if (field.getCardinality() == Cardinality.MANY && field.getNodeType().getKind() == TypeKind.ARRAY) { - type = ((ArrayType) field.getNodeType()).getComponentType(); - } else { - type = field.getNodeType(); - } - - signatureTypes.add(type); + + for (ActualParameter parameter : data.getSignatureParameters()) { + signatureTypes.add(parameter.getSpecification().getExecution().getNodeType()); } builder.startReturn().tree(createAsList(builder, signatureTypes, classType)).end(); @@ -1014,16 +1001,13 @@ CodeTreeBuilder oldBuilder = builder.create(); CodeTreeBuilder resetBuilder = builder.create(); - for (ActualParameter param : getModel().getParameters()) { - if (!param.getSpecification().isSignature()) { - continue; - } - NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); + for (ActualParameter param : getModel().getSignatureParameters()) { + NodeChildData child = param.getSpecification().getExecution().getChild(); CodeTreeBuilder access = builder.create(); access.string("this.").string(child.getName()); if (child.getCardinality().isMany()) { - access.string("[").string(String.valueOf(param.getSpecificationIndex())).string("]"); + access.string("[").string(String.valueOf(param.getSpecificationVarArgsIndex())).string("]"); } String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName()); @@ -1117,11 +1101,7 @@ builder.startStatement().startCall("builder", "append").doubleQuote(" (").end().end(); String sep = null; - for (ActualParameter parameter : node.getGenericSpecialization().getParameters()) { - if (!parameter.getSpecification().isSignature()) { - continue; - } - + for (ActualParameter parameter : node.getGenericSpecialization().getSignatureParameters()) { builder.startStatement(); builder.string("builder"); if (sep != null) { @@ -1210,15 +1190,6 @@ } } - for (VariableElement var : type.getFields()) { - NodeChildData child = node.findChild(var.getSimpleName().toString()); - if (child != null) { - method.getParameters().add(new CodeVariableElement(child.getOriginalType(), child.getName())); - } else { - method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString())); - } - } - if (superConstructor != null) { builder.startStatement().startSuperCall(); for (VariableElement param : superConstructor.getParameters()) { @@ -1228,11 +1199,18 @@ } for (VariableElement var : type.getFields()) { + NodeExecutionData execution = node.findExecution(var.getSimpleName().toString()); + NodeChildData child = execution != null ? execution.getChild() : null; + + if (execution != null) { + method.getParameters().add(new CodeVariableElement(execution.getNodeType(), execution.getName())); + } else { + method.getParameters().add(new CodeVariableElement(var.asType(), var.getSimpleName().toString())); + } + builder.startStatement(); String fieldName = var.getSimpleName().toString(); - NodeChildData child = node.findChild(fieldName); - CodeTree init = createStaticCast(builder, child, fieldName); init = createAdoptChild(builder, var.asType(), init); @@ -1520,19 +1498,15 @@ } } - NodeChildData child = node.findChild(valueParam.getSpecification().getName()); - if (child == null) { - throw new IllegalStateException(); - } - - CodeTree implicitGuard = createTypeGuard(guardsBuilder, child, valueParam, typeGuard.getType(), typedCasts); + NodeExecutionData execution = valueParam.getSpecification().getExecution(); + CodeTree implicitGuard = createTypeGuard(guardsBuilder, execution, valueParam, typeGuard.getType(), typedCasts); if (implicitGuard != null) { guardsBuilder.string(guardsAnd); guardsBuilder.tree(implicitGuard); guardsAnd = " && "; } - CodeTree cast = createCast(castBuilder, child, valueParam, typeGuard.getType(), checkMinimumState, typedCasts); + CodeTree cast = createCast(castBuilder, execution, valueParam, typeGuard.getType(), checkMinimumState, typedCasts); if (cast != null) { castBuilder.tree(cast); } @@ -1604,8 +1578,8 @@ return false; } - private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType, boolean typedCasts) { - NodeData node = field.getNodeData(); + private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeExecutionData execution, ActualParameter source, TypeData targetType, boolean typedCasts) { + NodeData node = execution.getChild().getNodeData(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); @@ -1617,7 +1591,7 @@ builder.startGroup(); - if (field.isShortCircuit()) { + if (execution.isShortCircuit()) { ActualParameter shortCircuit = source.getPreviousParameter(); assert shortCircuit != null; builder.string("("); @@ -1644,7 +1618,7 @@ } builder.end().end(); // call - if (field.isShortCircuit()) { + if (execution.isShortCircuit()) { builder.string(")"); } @@ -1654,8 +1628,8 @@ } // TODO merge redundancies with #createTypeGuard - private CodeTree createCast(CodeTreeBuilder parent, NodeChildData field, ActualParameter source, TypeData targetType, boolean checkMinimumState, boolean typedCasts) { - NodeData node = field.getNodeData(); + private CodeTree createCast(CodeTreeBuilder parent, NodeExecutionData execution, ActualParameter source, TypeData targetType, boolean checkMinimumState, boolean typedCasts) { + NodeData node = execution.getChild().getNodeData(); TypeData sourceType = source.getTypeSystemType(); if (!sourceType.needsCastTo(getContext(), targetType)) { @@ -1663,7 +1637,7 @@ } CodeTree condition = null; - if (field.isShortCircuit()) { + if (execution.isShortCircuit()) { ActualParameter shortCircuit = source.getPreviousParameter(); assert shortCircuit != null; condition = CodeTreeBuilder.singleString(valueName(shortCircuit)); @@ -1836,11 +1810,8 @@ replaceCall.startCall("replace"); } replaceCall.startGroup().startNew(className).string(source); - for (ActualParameter param : current.getParameters()) { - if (!param.getSpecification().isSignature()) { - continue; - } - NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); + for (ActualParameter param : current.getSignatureParameters()) { + NodeChildData child = param.getSpecification().getExecution().getChild(); List types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); if (types.size() > 1) { replaceCall.string(implicitTypeName(param)); @@ -1897,11 +1868,7 @@ boolean returnVoid = type.isVoid(); List executeParameters = new ArrayList<>(); - for (ActualParameter sourceParameter : executable.getParameters()) { - if (!sourceParameter.getSpecification().isSignature()) { - continue; - } - + for (ActualParameter sourceParameter : executable.getSignatureParameters()) { ActualParameter targetParameter = castExecutable.findParameter(sourceParameter.getLocalName()); if (targetParameter != null) { executeParameters.add(targetParameter); @@ -1968,14 +1935,13 @@ protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List targetParameters, ActualParameter unexpectedParameter) { CodeTreeBuilder builder = parent.create(); - NodeData node = specialization.getNode(); for (ActualParameter targetParameter : targetParameters) { - NodeChildData child = node.findChild(targetParameter.getSpecification().getName()); if (!targetParameter.getSpecification().isSignature()) { continue; } - CodeTree executionExpressions = createExecuteChild(builder, child, sourceExecutable, targetParameter, unexpectedParameter); - CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, specialization, sourceExecutable, targetParameter, isShortCircuit(child), unexpectedParameter); + NodeExecutionData execution = targetParameter.getSpecification().getExecution(); + CodeTree executionExpressions = createExecuteChild(builder, execution, sourceExecutable, targetParameter, unexpectedParameter); + CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, specialization, sourceExecutable, targetParameter, execution.isShortCircuit(), unexpectedParameter); CodeTree shortCircuitTree = createShortCircuitTree(builder, unexpectedTree, specialization, targetParameter, unexpectedParameter); if (shortCircuitTree == executionExpressions) { @@ -1993,15 +1959,16 @@ return builder.getRoot(); } - private ExecutableTypeData resolveExecutableType(NodeChildData child, TypeData type) { - ExecutableTypeData targetExecutable = child.findExecutableType(getContext(), type); + private ExecutableTypeData resolveExecutableType(NodeExecutionData execution, TypeData type) { + ExecutableTypeData targetExecutable = execution.getChild().findExecutableType(getContext(), type); if (targetExecutable == null) { - targetExecutable = child.findAnyGenericExecutableType(getContext()); + targetExecutable = execution.getChild().findAnyGenericExecutableType(getContext()); } return targetExecutable; } - private CodeTree createExecuteChild(CodeTreeBuilder parent, NodeChildData child, ExecutableTypeData sourceExecutable, ActualParameter targetParameter, ActualParameter unexpectedParameter) { + private CodeTree createExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, ActualParameter targetParameter, + ActualParameter unexpectedParameter) { SpecializationData specialization = getModel(); TreeSet possiblePolymorphicTypes = lookupPolymorphicTargetTypes(targetParameter); if (specialization.isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null && possiblePolymorphicTypes.size() > 1) { @@ -2020,28 +1987,25 @@ builder.string(polymorphicTypeName(targetParameter)).string(" == ").typeLiteral(possiblePolymoprhicType.getPrimitiveType()); builder.end().startBlock(); builder.startStatement(); - builder.tree(createExecuteChildExpression(parent, child, sourceType, new ActualParameter(targetParameter, possiblePolymoprhicType), unexpectedParameter, null)); + builder.tree(createExecuteChildExpression(parent, execution, sourceType, new ActualParameter(targetParameter, possiblePolymoprhicType), unexpectedParameter, null)); builder.end(); builder.end(); } builder.startElseBlock(); - builder.startStatement().tree(createExecuteChildImplicit(parent, child, sourceExecutable, targetParameter, unexpectedParameter)).end(); + builder.startStatement().tree(createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter)).end(); builder.end(); return builder.getRoot(); } else { - return createExecuteChildImplicit(parent, child, sourceExecutable, targetParameter, unexpectedParameter); + return createExecuteChildImplicit(parent, execution, sourceExecutable, targetParameter, unexpectedParameter); } } protected final List getImplicitTypeParamters(SpecializationData model) { List parameter = new ArrayList<>(); - for (ActualParameter param : model.getParameters()) { - if (!param.getSpecification().isSignature()) { - continue; - } - NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); + for (ActualParameter param : model.getSignatureParameters()) { + NodeChildData child = param.getSpecification().getExecution().getChild(); List types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); if (types.size() > 1) { parameter.add(param); @@ -2065,7 +2029,7 @@ return possiblePolymorphicTypes; } - private CodeTree createExecuteChildImplicit(CodeTreeBuilder parent, NodeChildData child, ExecutableTypeData sourceExecutable, ActualParameter param, ActualParameter unexpectedParameter) { + private CodeTree createExecuteChildImplicit(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, ActualParameter param, ActualParameter unexpectedParameter) { CodeTreeBuilder builder = parent.create(); ActualParameter sourceParameter = sourceExecutable.findParameter(param.getLocalName()); String childExecuteName = createExecuteChildMethodName(param, sourceParameter != null); @@ -2089,19 +2053,20 @@ builder.end(); } else { - List sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); + List sourceTypes = execution.getChild().getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); TypeData expectType = sourceParameter != null ? sourceParameter.getTypeSystemType() : null; if (sourceTypes.size() > 1) { builder.tree(createExecuteChildImplicitExpressions(parent, param, expectType)); } else { - builder.tree(createExecuteChildExpression(parent, child, expectType, param, unexpectedParameter, null)); + builder.tree(createExecuteChildExpression(parent, execution, expectType, param, unexpectedParameter, null)); } } return builder.getRoot(); } private String createExecuteChildMethodName(ActualParameter param, boolean expect) { - NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); + NodeExecutionData execution = param.getSpecification().getExecution(); + NodeChildData child = execution.getChild(); if (child.getExecuteWith().size() > 0) { return null; } @@ -2110,7 +2075,8 @@ return null; } String prefix = expect ? "expect" : "execute"; - return prefix + Utils.firstLetterUpperCase(child.getName()) + Utils.firstLetterUpperCase(Utils.getSimpleName(param.getType())) + param.getSpecificationIndex(); + String suffix = execution.getIndex() > -1 ? String.valueOf(execution.getIndex()) : ""; + return prefix + Utils.firstLetterUpperCase(child.getName()) + Utils.firstLetterUpperCase(Utils.getSimpleName(param.getType())) + suffix; } private List createExecuteChilds(ActualParameter param, Set expectTypes) { @@ -2155,7 +2121,7 @@ private CodeTree createExecuteChildImplicitExpressions(CodeTreeBuilder parent, ActualParameter targetParameter, TypeData expectType) { CodeTreeBuilder builder = parent.create(); NodeData node = getModel().getNode(); - NodeChildData child = node.findChild(targetParameter.getSpecification().getName()); + NodeExecutionData execution = targetParameter.getSpecification().getExecution(); List sourceTypes = node.getTypeSystem().lookupSourceTypes(targetParameter.getTypeSystemType()); boolean elseIf = false; int index = 0; @@ -2169,18 +2135,18 @@ builder.startElseBlock(); } - ExecutableTypeData implictExecutableTypeData = child.findExecutableType(getContext(), sourceType); + ExecutableTypeData implictExecutableTypeData = execution.getChild().findExecutableType(getContext(), sourceType); if (implictExecutableTypeData == null) { /* * For children with executeWith.size() > 0 an executable type may not exist so * use the generic executable type which is guaranteed to exist. An expect call * is inserted automatically by #createExecuteExpression. */ - implictExecutableTypeData = child.getNodeData().findExecutableType(node.getTypeSystem().getGenericTypeData(), child.getExecuteWith().size()); + implictExecutableTypeData = execution.getChild().getNodeData().findExecutableType(node.getTypeSystem().getGenericTypeData(), execution.getChild().getExecuteWith().size()); } - ImplicitCastData cast = child.getNodeData().getTypeSystem().lookupCast(sourceType, targetParameter.getTypeSystemType()); - CodeTree execute = createExecuteChildExpression(builder, child, expectType, targetParameter, null, cast); + ImplicitCastData cast = execution.getChild().getNodeData().getTypeSystem().lookupCast(sourceType, targetParameter.getTypeSystemType()); + CodeTree execute = createExecuteChildExpression(builder, execution, expectType, targetParameter, null, cast); builder.statement(execute); builder.end(); index++; @@ -2188,8 +2154,8 @@ return builder.getRoot(); } - private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeChildData child, TypeData sourceParameterType, ActualParameter targetParameter, ActualParameter unexpectedParameter, - ImplicitCastData cast) { + private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData execution, TypeData sourceParameterType, ActualParameter targetParameter, + ActualParameter unexpectedParameter, ImplicitCastData cast) { // assignments: targetType <- castTargetType <- castSourceType <- sourceType TypeData sourceType = sourceParameterType; TypeData targetType = targetParameter.getTypeSystemType(); @@ -2203,15 +2169,15 @@ CodeTree expression; if (sourceType == null) { - ExecutableTypeData targetExecutable = resolveExecutableType(child, castSourceType); - expression = createExecuteChildExpression(parent, child, targetParameter, targetExecutable, unexpectedParameter); + ExecutableTypeData targetExecutable = resolveExecutableType(execution, castSourceType); + expression = createExecuteChildExpression(parent, execution, targetExecutable, unexpectedParameter); sourceType = targetExecutable.getType(); } else { expression = CodeTreeBuilder.singleString(valueNameEvaluated(targetParameter)); } // target = expectTargetType(implicitCast(expectCastSourceType(source))) - TypeSystemData typeSystem = child.getNodeData().getTypeSystem(); + TypeSystemData typeSystem = execution.getChild().getNodeData().getTypeSystem(); expression = createExpectType(typeSystem, sourceType, castSourceType, expression); expression = createImplicitCast(parent, typeSystem, cast, expression); expression = createExpectType(typeSystem, castTargetType, targetType, expression); @@ -2248,32 +2214,32 @@ } private boolean hasUnexpected(ActualParameter sourceParameter, ActualParameter targetParameter, ActualParameter unexpectedParameter) { - NodeChildData child = getModel().getNode().findChild(targetParameter.getSpecification().getName()); + NodeExecutionData execution = targetParameter.getSpecification().getExecution(); if (getModel().isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { // check for other polymorphic types TreeSet polymorphicTargetTypes = lookupPolymorphicTargetTypes(targetParameter); if (polymorphicTargetTypes.size() > 1) { for (TypeData polymorphicTargetType : polymorphicTargetTypes) { - if (hasUnexpectedType(child, sourceParameter, polymorphicTargetType)) { + if (hasUnexpectedType(execution, sourceParameter, polymorphicTargetType)) { return true; } } } } - if (hasUnexpectedType(child, sourceParameter, targetParameter.getTypeSystemType())) { + if (hasUnexpectedType(execution, sourceParameter, targetParameter.getTypeSystemType())) { return true; } return false; } - private boolean hasUnexpectedType(NodeChildData child, ActualParameter sourceParameter, TypeData targetType) { + private boolean hasUnexpectedType(NodeExecutionData execution, ActualParameter sourceParameter, TypeData targetType) { List implicitSourceTypes = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); for (TypeData implicitSourceType : implicitSourceTypes) { TypeData sourceType; - ExecutableTypeData targetExecutable = resolveExecutableType(child, implicitSourceType); + ExecutableTypeData targetExecutable = resolveExecutableType(execution, implicitSourceType); if (sourceParameter != null) { sourceType = sourceParameter.getTypeSystemType(); } else { @@ -2357,11 +2323,10 @@ return builder.getRoot(); } - private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeChildData targetChild, ActualParameter targetParameter, ExecutableTypeData targetExecutable, - ActualParameter unexpectedParameter) { + private CodeTree createExecuteChildExpression(CodeTreeBuilder parent, NodeExecutionData targetExecution, ExecutableTypeData targetExecutable, ActualParameter unexpectedParameter) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); - if (targetChild != null) { - builder.tree(createAccessChild(builder, targetChild, targetParameter)); + if (targetExecution != null) { + builder.tree(createAccessChild(builder, targetExecution)); builder.string("."); } @@ -2375,8 +2340,8 @@ builder.string(parameter.getLocalName()); } else { - if (index < targetChild.getExecuteWith().size()) { - NodeChildData child = targetChild.getExecuteWith().get(index); + if (index < targetExecution.getChild().getExecuteWith().size()) { + NodeChildData child = targetExecution.getChild().getExecuteWith().get(index); ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName()); List specializationParams = getModel().findParameters(spec); @@ -2415,31 +2380,31 @@ return builder.getRoot(); } - private CodeTree createAccessChild(CodeTreeBuilder parent, NodeChildData targetChild, ActualParameter targetParameter) throws AssertionError { + private CodeTree createAccessChild(CodeTreeBuilder parent, NodeExecutionData targetExecution) throws AssertionError { CodeTreeBuilder builder = parent.create(); - Element accessElement = targetChild.getAccessElement(); + Element accessElement = targetExecution.getChild().getAccessElement(); if (accessElement == null || accessElement.getKind() == ElementKind.METHOD) { - builder.string("this.").string(targetChild.getName()); + 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 (targetParameter.getSpecification().isIndexed()) { - builder.string("[" + targetParameter.getSpecificationIndex() + "]"); + if (targetExecution.isIndexed()) { + builder.string("[" + targetExecution.getIndex() + "]"); } return builder.getRoot(); } private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, ActualParameter parameter, ActualParameter exceptionParam) { - NodeChildData forField = specialization.getNode().findChild(parameter.getSpecification().getName()); - if (!isShortCircuit(forField)) { + NodeExecutionData execution = parameter.getSpecification().getExecution(); + if (execution == null || !execution.isShortCircuit()) { return body; } CodeTreeBuilder builder = new CodeTreeBuilder(parent); ActualParameter shortCircuitParam = specialization.getPreviousParam(parameter); - builder.tree(createShortCircuitValue(builder, specialization, forField, shortCircuitParam, exceptionParam)); + builder.tree(createShortCircuitValue(builder, specialization, execution, shortCircuitParam, exceptionParam)); builder.declaration(parameter.getType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getType())); builder.startIf().string(shortCircuitParam.getLocalName()).end(); builder.startBlock(); @@ -2454,16 +2419,13 @@ return builder.getRoot(); } - private boolean isShortCircuit(NodeChildData forField) { - return forField != null && forField.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT; - } - - private CodeTree createShortCircuitValue(CodeTreeBuilder parent, SpecializationData specialization, NodeChildData forField, ActualParameter shortCircuitParam, ActualParameter exceptionParam) { + private CodeTree createShortCircuitValue(CodeTreeBuilder parent, SpecializationData specialization, NodeExecutionData execution, ActualParameter shortCircuitParam, + ActualParameter exceptionParam) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); int shortCircuitIndex = 0; - for (NodeChildData field : specialization.getNode().getChildren()) { - if (field.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) { - if (field == forField) { + for (NodeExecutionData otherExectuion : specialization.getNode().getChildExecutions()) { + if (otherExectuion.isShortCircuit()) { + if (otherExectuion == execution) { break; } shortCircuitIndex++; @@ -2856,39 +2818,43 @@ int signatureIndex = -1; for (VariableElement param : method.getParameters()) { CodeVariableElement var = CodeVariableElement.clone(param); - ActualParameter actualParameter = execType.getParameters().get(i); - if (actualParameter.getSpecification().isSignature()) { - signatureIndex++; - } - + ActualParameter actualParameter = i < execType.getParameters().size() ? execType.getParameters().get(i) : null; String name; - if (evaluated && actualParameter.getSpecification().isSignature()) { - name = valueNameEvaluated(actualParameter); - } else { - name = valueName(actualParameter); - } - - int varArgCount = getModel().getSignatureSize() - signatureIndex; - if (evaluated && actualParameter.isVarArgs()) { - ActualParameter baseVarArgs = actualParameter; - name = valueName(baseVarArgs) + "Args"; - - builder.startAssert().string(name).string(" != null").end(); - builder.startAssert().string(name).string(".length == ").string(String.valueOf(varArgCount)).end(); - if (varArgCount > 0) { - List varArgsParameter = execType.getParameters().subList(i, execType.getParameters().size()); - for (ActualParameter varArg : varArgsParameter) { - if (varArgCount <= 0) { - break; + if (actualParameter != null) { + if (actualParameter.getSpecification().isSignature()) { + signatureIndex++; + } + + if (evaluated && actualParameter.getSpecification().isSignature()) { + name = valueNameEvaluated(actualParameter); + } else { + name = valueName(actualParameter); + } + + int varArgCount = getModel().getSignatureSize() - signatureIndex; + if (evaluated && actualParameter.isTypeVarArgs()) { + ActualParameter baseVarArgs = actualParameter; + name = valueName(baseVarArgs) + "Args"; + + builder.startAssert().string(name).string(" != null").end(); + builder.startAssert().string(name).string(".length == ").string(String.valueOf(varArgCount)).end(); + if (varArgCount > 0) { + List varArgsParameter = execType.getParameters().subList(i, execType.getParameters().size()); + for (ActualParameter varArg : varArgsParameter) { + if (varArgCount <= 0) { + break; + } + TypeMirror type = baseVarArgs.getType(); + if (type.getKind() == TypeKind.ARRAY) { + type = ((ArrayType) type).getComponentType(); + } + builder.declaration(type, valueNameEvaluated(varArg), name + "[" + varArg.getTypeVarArgsIndex() + "]"); + varArgCount--; } - TypeMirror type = baseVarArgs.getType(); - if (type.getKind() == TypeKind.ARRAY) { - type = ((ArrayType) type).getComponentType(); - } - builder.declaration(type, valueNameEvaluated(varArg), name + "[" + varArg.getVarArgsIndex() + "]"); - varArgCount--; } } + } else { + name = "arg" + i; } var.setName(name); method.getParameters().set(i, var); diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeData.java Tue Jan 07 12:22:47 2014 +0100 @@ -28,7 +28,6 @@ import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.node.NodeChildData.*; import com.oracle.truffle.dsl.processor.template.*; import com.oracle.truffle.dsl.processor.typesystem.*; @@ -41,6 +40,7 @@ private TypeSystemData typeSystem; private List children; + private List childExecutions; private List fields; private TypeMirror nodeType; private ParameterSpec instanceParameterSpec; @@ -78,6 +78,14 @@ this.assumptions = splitSource.assumptions; } + public List getChildExecutions() { + return childExecutions; + } + + void setChildExecutions(List signature) { + this.childExecutions = signature; + } + public int getSignatureSize() { if (getSpecializations() != null && !getSpecializations().isEmpty()) { return getSpecializations().get(0).getSignatureSize(); @@ -374,16 +382,6 @@ return result; } - public NodeChildData[] filterFields(ExecutionKind usage) { - List filteredFields = new ArrayList<>(); - for (NodeChildData field : getChildren()) { - if (usage == null || field.getExecutionKind() == usage) { - filteredFields.add(field); - } - } - return filteredFields.toArray(new NodeChildData[filteredFields.size()]); - } - public boolean needsRewrites(ProcessorContext context) { boolean needsRewrites = false; @@ -490,6 +488,18 @@ return b.toString(); } + public NodeExecutionData findExecution(String name) { + if (getChildExecutions() == null) { + return null; + } + for (NodeExecutionData execution : getChildExecutions()) { + if (execution.getName().equals(name)) { + return execution; + } + } + return null; + } + public NodeChildData findChild(String name) { for (NodeChildData field : getChildren()) { if (field.getName().equals(name)) { @@ -593,4 +603,5 @@ public int compareTo(NodeData o) { return getNodeId().compareTo(o.getNodeId()); } + } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeExecutionData.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeExecutionData.java Tue Jan 07 12:22:47 2014 +0100 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.dsl.processor.node; + +import javax.lang.model.type.*; + +import com.oracle.truffle.dsl.processor.node.NodeChildData.*; + +public class NodeExecutionData { + + private final NodeChildData child; + private final String name; + private final int index; + private final boolean shortCircuit; + + public NodeExecutionData(NodeChildData child, int index, boolean shortCircuit) { + this.child = child; + this.index = index; + this.shortCircuit = shortCircuit; + this.name = createName(); + } + + private String createName() { + if (isIndexed()) { + return child.getName() + index; + } + return child.getName(); + } + + public TypeMirror getNodeType() { + TypeMirror type; + if (child.getCardinality() == Cardinality.MANY && child.getNodeType().getKind() == TypeKind.ARRAY) { + type = ((ArrayType) child.getNodeType()).getComponentType(); + } else { + type = child.getNodeType(); + } + return type; + } + + public String getName() { + return name; + } + + public NodeChildData getChild() { + return child; + } + + public int getIndex() { + return index; + } + + public boolean isIndexed() { + return index > -1; + } + + public boolean isShortCircuit() { + return shortCircuit; + } + + public String getShortCircuitId() { + return createShortCircuitId(child, index); + } + + public static String createShortCircuitId(NodeChildData child, int varArgsIndex) { + String shortCircuitName = child.getName(); + if (child.getCardinality().isMany()) { + shortCircuitName = shortCircuitName + "[" + varArgsIndex + "]"; + } + return shortCircuitName; + } + +} diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeMethodParser.java Tue Jan 07 12:22:47 2014 +0100 @@ -28,7 +28,6 @@ import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.node.NodeChildData.*; import com.oracle.truffle.dsl.processor.template.*; public abstract class NodeMethodParser extends TemplateMethodParser { @@ -41,10 +40,9 @@ return template; } - @SuppressWarnings("unused") - protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, int evaluatedCount) { - ParameterSpec spec = new ParameterSpec(valueName, nodeTypeMirrors(nodeData)); - spec.setSignature(true); + protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) { + ParameterSpec spec = new ParameterSpec(execution.getName(), nodeTypeMirrors(execution.getChild().getNodeData())); + spec.setExecution(execution); return spec; } @@ -61,7 +59,7 @@ } protected ParameterSpec createReturnParameterSpec() { - return createValueParameterSpec("returnValue", getNode(), 0); + return new ParameterSpec("returnValue", nodeTypeMirrors(getNode())); } @Override @@ -85,31 +83,21 @@ return methodSpec; } - public void addDefaultChildren(boolean shortCircuitsEnabled, String breakName, MethodSpec methodSpec) { - // children are null when parsing executable types - if (getNode().getChildren() != null) { - for (NodeChildData child : getNode().getChildren()) { - String valueName = child.getName(); - if (breakName != null && valueName.equals(breakName)) { - break; - } - if (child.getExecutionKind() == ExecutionKind.DEFAULT) { - ParameterSpec spec = createValueParameterSpec(child.getName(), child.getNodeData(), child.getExecuteWith().size()); - if (child.getCardinality().isMany()) { - spec.setCardinality(Cardinality.MANY); - spec.setIndexed(true); - } - methodSpec.addRequired(spec); - } else if (child.getExecutionKind() == ExecutionKind.SHORT_CIRCUIT) { + public void addDefaultChildren(boolean shortCircuitsEnabled, String breakName, MethodSpec spec) { + if (getNode().getChildren() == null) { + // children are null when parsing executable types + return; + } - if (shortCircuitsEnabled) { - methodSpec.addRequired(new ParameterSpec(shortCircuitValueName(valueName), getContext().getType(boolean.class))); - } - methodSpec.addRequired(createValueParameterSpec(valueName, child.getNodeData(), child.getExecuteWith().size())); - } else { - assert false; - } + for (NodeExecutionData execution : getNode().getChildExecutions()) { + if (breakName != null && execution.getShortCircuitId().equals(breakName)) { + break; } + + if (execution.isShortCircuit() && shortCircuitsEnabled) { + spec.addRequired(new ParameterSpec(shortCircuitValueName(execution.getName()), getContext().getType(boolean.class))); + } + spec.addRequired(createValueParameterSpec(execution)); } } @@ -130,6 +118,9 @@ } protected void addDefaultImplicitThis(ExecutableElement method, MethodSpec methodSpec) { + if (method == null) { + return; + } TypeMirror declaredType = Utils.findNearestEnclosingType(method).asType(); if (!method.getModifiers().contains(Modifier.STATIC) && !Utils.isAssignable(getContext(), declaredType, getContext().getTruffleTypes().getNode())) { diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeParser.java Tue Jan 07 12:22:47 2014 +0100 @@ -34,9 +34,8 @@ import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.node.NodeChildData.Cardinality; -import com.oracle.truffle.dsl.processor.node.NodeChildData.ExecutionKind; import com.oracle.truffle.dsl.processor.template.*; -import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature; +import com.oracle.truffle.dsl.processor.template.TemplateMethod.TypeSignature; import com.oracle.truffle.dsl.processor.typesystem.*; public class NodeParser extends TemplateParser { @@ -205,7 +204,6 @@ finalizeSpecializations(elements, splittedNode); verifyNode(splittedNode, elements); - expandExecutableTypeVarArgs(splittedNode); createPolymorphicSpecializations(splittedNode); assignShortCircuitsToSpecializations(splittedNode); } @@ -218,26 +216,6 @@ return node; } - private static void expandExecutableTypeVarArgs(NodeData node) { - for (ExecutableTypeData executableMethod : node.getExecutableTypes()) { - if (!(executableMethod.getMethod().isVarArgs() && executableMethod.getSpecification().isVariableRequiredArguments())) { - continue; - } - int expandArguments = node.getSignatureSize() - executableMethod.getSignatureSize(); - if (expandArguments > 0) { - int signatureSize = executableMethod.getSignatureSize(); - ActualParameter parameter = executableMethod.getSignatureParameter(signatureSize - 1); - for (int i = 0; i < expandArguments; i++) { - int newVarArgsIndex = parameter.getVarArgsIndex() + i + 1; - int newSpecificationIndex = parameter.getSpecificationIndex() + i + 1; - executableMethod.getParameters().add( - new ActualParameter(parameter.getSpecification(), parameter.getTypeSystemType(), newSpecificationIndex, newVarArgsIndex, parameter.isImplicit())); - } - - } - } - } - private void createPolymorphicSpecializations(NodeData node) { if (!node.needsRewrites(context) || !node.isPolymorphic()) { node.setPolymorphicSpecializations(Collections. emptyList()); @@ -277,7 +255,7 @@ } SpecializationData specialization = new SpecializationData(generic, false, false, true); - specialization.updateSignature(new Signature(polymorphicSignature)); + specialization.updateSignature(new TypeSignature(polymorphicSignature)); specialization.setNode(node); node.setGenericPolymorphicSpecialization(specialization); // TODO remove polymoprhic specializations @@ -336,6 +314,7 @@ nodeData.setTypeSystem(typeSystem); nodeData.setFields(parseFields(typeHierarchy, elements)); nodeData.setChildren(parseChildren(nodeData, elements, typeHierarchy)); + nodeData.setChildExecutions(parseDefaultSignature(nodeData, elements)); nodeData.setExecutableTypes(groupExecutableTypes(new ExecutableTypeMethodParser(context, nodeData).parse(elements))); // resolveChildren invokes cyclic parsing. @@ -345,6 +324,90 @@ return nodeData; } + private List parseDefaultSignature(NodeData node, List elements) { + if (node.getChildren() == null) { + return null; + } + + // pre-parse short circuits + Set shortCircuits = new HashSet<>(); + List methods = ElementFilter.methodsIn(elements); + for (ExecutableElement method : methods) { + AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class); + if (mirror != null) { + shortCircuits.add(Utils.getAnnotationValue(String.class, mirror, "value")); + } + } + + boolean hasVarArgs = false; + int maxSignatureSize = 0; + if (!node.getChildren().isEmpty()) { + int lastIndex = node.getChildren().size() - 1; + hasVarArgs = node.getChildren().get(lastIndex).getCardinality() == Cardinality.MANY; + if (hasVarArgs) { + maxSignatureSize = lastIndex; + } else { + maxSignatureSize = node.getChildren().size(); + } + } + + // pre-parse specializations + for (ExecutableElement method : methods) { + AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, Specialization.class); + if (mirror == null) { + continue; + } + + int currentArgumentCount = 0; + boolean skipShortCircuit = false; + for (VariableElement var : method.getParameters()) { + TypeMirror type = var.asType(); + if (currentArgumentCount == 0) { + // skip optionals + if (Utils.typeEquals(type, context.getTruffleTypes().getFrame())) { + continue; + } + // TODO skip optional fields? + } + int childIndex = currentArgumentCount < node.getChildren().size() ? currentArgumentCount : node.getChildren().size() - 1; + if (childIndex == -1) { + continue; + } + if (!skipShortCircuit) { + NodeChildData child = node.getChildren().get(childIndex); + if (shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, currentArgumentCount - childIndex))) { + skipShortCircuit = true; + continue; + } + } else { + skipShortCircuit = false; + } + + currentArgumentCount++; + } + maxSignatureSize = Math.max(maxSignatureSize, currentArgumentCount); + } + + List executions = new ArrayList<>(); + for (int i = 0; i < maxSignatureSize; i++) { + int childIndex = i; + boolean varArg = false; + if (childIndex >= node.getChildren().size() - 1) { + if (hasVarArgs) { + childIndex = node.getChildren().size() - 1; + varArg = hasVarArgs; + } else if (childIndex >= node.getChildren().size()) { + break; + } + } + int varArgsIndex = varArg ? Math.abs(childIndex - i) : -1; + NodeChildData child = node.getChildren().get(childIndex); + boolean shortCircuit = shortCircuits.contains(NodeExecutionData.createShortCircuitId(child, varArgsIndex)); + executions.add(new NodeExecutionData(child, varArgsIndex, shortCircuit)); + } + return executions; + } + private List parseFields(List typeHierarchy, List elements) { Set names = new HashSet<>(); @@ -470,12 +533,7 @@ Element getter = findGetter(elements, name, childType); - ExecutionKind kind = ExecutionKind.DEFAULT; - if (shortCircuits.contains(name)) { - kind = ExecutionKind.SHORT_CIRCUIT; - } - - NodeChildData nodeChild = new NodeChildData(parent, type, childMirror, name, childType, originalChildType, getter, cardinality, kind); + NodeChildData nodeChild = new NodeChildData(parent, type, childMirror, name, childType, originalChildType, getter, cardinality); parsedChildren.add(nodeChild); @@ -727,62 +785,64 @@ } private SpecializationData createGenericSpecialization(final NodeData node, List specializations) { - SpecializationData genericSpecialization; SpecializationData specialization = specializations.get(0); GenericParser parser = new GenericParser(context, node); MethodSpec specification = parser.createDefaultMethodSpec(specialization.getMethod(), null, true, null); + specification.getImplicitRequiredTypes().clear(); - List parameters = new ArrayList<>(); - for (ActualParameter parameter : specialization.getReturnTypeAndParameters()) { - if (!parameter.getSpecification().isSignature()) { - parameters.add(new ActualParameter(parameter)); - continue; + List parameterTypes = new ArrayList<>(); + int signatureIndex = 1; + for (ParameterSpec spec : specification.getRequired()) { + parameterTypes.add(createGenericType(spec, specializations, signatureIndex)); + if (spec.isSignature()) { + signatureIndex++; } - NodeData childNode = node; - NodeChildData child = node.findChild(parameter.getSpecification().getName()); - if (child != null) { - childNode = child.getNodeData(); + } + TypeMirror returnType = createGenericType(specification.getReturnType(), specializations, 0); + return parser.create("Generic", null, null, returnType, parameterTypes); + } + + private TypeMirror createGenericType(ParameterSpec spec, List specializations, int signatureIndex) { + NodeExecutionData execution = spec.getExecution(); + if (execution == null) { + if (spec.getAllowedTypes().size() == 1) { + return spec.getAllowedTypes().get(0); + } else { + return Utils.getCommonSuperType(context, spec.getAllowedTypes().toArray(new TypeMirror[0])); + } + } else { + Set types = new HashSet<>(); + for (SpecializationData specialization : specializations) { + types.add(specialization.getTypeSignature().get(signatureIndex)); } - TypeData genericType = null; + NodeChildData child = execution.getChild(); - Set types = new HashSet<>(); - for (SpecializationData otherSpecialization : specializations) { - ActualParameter otherParameter = otherSpecialization.findParameter(parameter.getLocalName()); - if (otherParameter != null) { - types.add(otherParameter.getTypeSystemType()); + TypeData genericType = null; + if (types.size() == 1) { + ExecutableTypeData executable = child.findExecutableType(context, types.iterator().next()); + if (executable != null && !executable.hasUnexpectedValue(context)) { + genericType = types.iterator().next(); } } - - assert !types.isEmpty(); - - if (types.size() == 1) { - ExecutableTypeData executable = childNode.findExecutableType(types.iterator().next(), 0); - if (executable != null && !executable.hasUnexpectedValue(context)) { - genericType = types.iterator().next(); - } else { - genericType = childNode.findAnyGenericExecutableType(context, 0).getType(); - } - } else { - genericType = childNode.findAnyGenericExecutableType(context, 0).getType(); + if (genericType == null) { + genericType = child.findAnyGenericExecutableType(context).getType(); } - - parameters.add(new ActualParameter(parameter, genericType)); + return genericType.getPrimitiveType(); } - ActualParameter returnType = parameters.get(0); - parameters = parameters.subList(1, parameters.size()); - - TemplateMethod genericMethod = new TemplateMethod("Generic", node, specification, null, null, returnType, parameters); - genericSpecialization = new SpecializationData(genericMethod, true, false, false); - return genericSpecialization; } private void assignShortCircuitsToSpecializations(NodeData node) { Map> groupedShortCircuits = groupShortCircuits(node.getShortCircuits()); boolean valid = true; - for (NodeChildData field : node.filterFields(ExecutionKind.SHORT_CIRCUIT)) { - String valueName = field.getName(); + List shortCircuitExecutions = new ArrayList<>(); + for (NodeExecutionData execution : node.getChildExecutions()) { + if (!execution.isShortCircuit()) { + continue; + } + shortCircuitExecutions.add(execution); + String valueName = execution.getShortCircuitId(); List availableCircuits = groupedShortCircuits.get(valueName); if (availableCircuits == null || availableCircuits.isEmpty()) { @@ -809,7 +869,7 @@ ShortCircuitData genericCircuit = null; for (ShortCircuitData circuit : availableCircuits) { - if (isGenericShortCutMethod(node, circuit)) { + if (isGenericShortCutMethod(circuit)) { genericCircuit = circuit; break; } @@ -832,16 +892,15 @@ return; } - NodeChildData[] fields = node.filterFields(ExecutionKind.SHORT_CIRCUIT); List specializations = new ArrayList<>(); specializations.addAll(node.getSpecializations()); specializations.addAll(node.getPolymorphicSpecializations()); for (SpecializationData specialization : specializations) { - List assignedShortCuts = new ArrayList<>(fields.length); + List assignedShortCuts = new ArrayList<>(shortCircuitExecutions.size()); - for (int i = 0; i < fields.length; i++) { - List availableShortCuts = groupedShortCircuits.get(fields[i].getName()); + for (NodeExecutionData shortCircuit : shortCircuitExecutions) { + List availableShortCuts = groupedShortCircuits.get(shortCircuit.getShortCircuitId()); ShortCircuitData genericShortCircuit = null; ShortCircuitData compatibleShortCircuit = null; @@ -897,7 +956,7 @@ List paramIds = new LinkedList<>(); paramIds.add(Utils.getTypeId(other.getReturnType().getType())); for (ActualParameter param : other.getParameters()) { - if (other.getNode().findChild(param.getSpecification().getName()) == null) { + if (param.getSpecification().getExecution() == null) { continue; } paramIds.add(Utils.getTypeId(param.getType())); @@ -1230,14 +1289,14 @@ return null; } - private boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) { + private boolean isGenericShortCutMethod(ShortCircuitData method) { for (ActualParameter parameter : method.getParameters()) { - NodeChildData field = node.findChild(parameter.getSpecification().getName()); - if (field == null) { + NodeExecutionData execution = parameter.getSpecification().getExecution(); + if (execution == null) { continue; } ExecutableTypeData found = null; - List executableElements = field.findGenericExecutableTypes(context); + List executableElements = execution.getChild().findGenericExecutableTypes(context); for (ExecutableTypeData executable : executableElements) { if (executable.getType().equalsType(parameter.getTypeSystemType())) { found = executable; diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/ShortCircuitParser.java Tue Jan 07 12:22:47 2014 +0100 @@ -29,7 +29,6 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.node.NodeChildData.*; import com.oracle.truffle.dsl.processor.template.*; public class ShortCircuitParser extends NodeMethodParser { @@ -40,15 +39,17 @@ super(context, node); shortCircuitValues = new HashSet<>(); - NodeChildData[] shortCircuitFields = node.filterFields(ExecutionKind.SHORT_CIRCUIT); - for (NodeChildData field : shortCircuitFields) { - shortCircuitValues.add(field.getName()); + for (NodeExecutionData execution : node.getChildExecutions()) { + if (execution.isShortCircuit()) { + shortCircuitValues.add(execution.getShortCircuitId()); + } } } @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { String shortCircuitValue = Utils.getAnnotationValue(String.class, mirror, "value"); + return createDefaultMethodSpec(method, mirror, true, shortCircuitValue); } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationData.java Tue Jan 07 12:22:47 2014 +0100 @@ -99,20 +99,12 @@ return false; } - for (ActualParameter parameter : getParameters()) { - if (!parameter.getSpecification().isSignature()) { - continue; - } - NodeChildData child = getNode().findChild(parameter.getSpecification().getName()); - if (child == null) { - continue; - } + for (ActualParameter parameter : getSignatureParameters()) { ActualParameter genericParameter = getNode().getGenericSpecialization().findParameter(parameter.getLocalName()); if (!parameter.getTypeSystemType().equals(genericParameter.getTypeSystemType())) { return false; } } - return true; } @@ -126,12 +118,8 @@ if (!getAssumptions().isEmpty()) { return true; } - for (ActualParameter parameter : getParameters()) { - NodeChildData child = getNode().findChild(parameter.getSpecification().getName()); - if (child == null) { - continue; - } - ExecutableTypeData type = child.findExecutableType(context, parameter.getTypeSystemType()); + for (ActualParameter parameter : getSignatureParameters()) { + ExecutableTypeData type = parameter.getSpecification().getExecution().getChild().findExecutableType(context, parameter.getTypeSystemType()); if (type.hasUnexpectedValue(context)) { return true; } @@ -254,7 +242,7 @@ @Override public String toString() { - return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getSignature()); + return String.format("%s [id = %s, method = %s, guards = %s, signature = %s]", getClass().getSimpleName(), getId(), getMethod(), getGuards(), getTypeSignature()); } public void forceFrame(TypeMirror frameType) { @@ -267,7 +255,7 @@ } public boolean equalsGuards(SpecializationData specialization) { - if (assumptions.equals(specialization.getAssumptions()) && guards.equals(specialization.getGuards()) && getSignature().equalsParameters(specialization.getSignature())) { + if (assumptions.equals(specialization.getAssumptions()) && guards.equals(specialization.getGuards()) && getTypeSignature().equalsParameters(specialization.getTypeSignature())) { return true; } return false; @@ -281,4 +269,5 @@ } return false; } + } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/SpecializationGroup.java Tue Jan 07 12:22:47 2014 +0100 @@ -28,7 +28,7 @@ import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.template.*; -import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature; +import com.oracle.truffle.dsl.processor.template.TemplateMethod.TypeSignature; import com.oracle.truffle.dsl.processor.typesystem.*; /** @@ -55,7 +55,7 @@ this.specialization = data; this.assumptions.addAll(data.getAssumptions()); - Signature sig = data.getSignature(); + TypeSignature sig = data.getTypeSignature(); for (int i = 1; i < sig.size(); i++) { typeGuards.add(new TypeGuard(sig.get(i), i - 1)); } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ActualParameter.java Tue Jan 07 12:22:47 2014 +0100 @@ -33,24 +33,24 @@ private TypeData typeSystemType; private TemplateMethod method; private final String localName; - private final int specificationIndex; - private final int varArgsIndex; + private final int specificationVarArgsIndex; + private final int typeVarArgsIndex; private final boolean implicit; - private final TypeMirror type; + private final TypeMirror actualType; - public ActualParameter(ParameterSpec specification, TypeMirror actualType, int specificationIndex, int varArgsIndex, boolean implicit) { + public ActualParameter(ParameterSpec specification, TypeMirror actualType, int specificationVarArgsIndex, int typeVarArgsIndex, boolean implicit) { this.specification = specification; - this.type = actualType; + this.actualType = actualType; this.typeSystemType = null; - this.specificationIndex = specificationIndex; + this.specificationVarArgsIndex = specificationVarArgsIndex; this.implicit = implicit; - String valueName = specification.getName() + "Value"; - if (specification.isIndexed()) { - valueName += specificationIndex; + String valueName = specification.getName() + "Value"; + if (specificationVarArgsIndex > -1) { + valueName += "_" + specificationVarArgsIndex; } - this.varArgsIndex = varArgsIndex; + this.typeVarArgsIndex = typeVarArgsIndex; this.localName = valueName; } @@ -60,29 +60,29 @@ } public ActualParameter(ActualParameter parameter, TypeData otherType) { - this(parameter.specification, otherType, parameter.specificationIndex, parameter.varArgsIndex, parameter.implicit); + this(parameter.specification, otherType, parameter.specificationVarArgsIndex, parameter.typeVarArgsIndex, parameter.implicit); } public ActualParameter(ActualParameter parameter) { this.specification = parameter.specification; - this.type = parameter.type; + this.actualType = parameter.actualType; this.typeSystemType = parameter.typeSystemType; - this.specificationIndex = parameter.specificationIndex; + this.specificationVarArgsIndex = parameter.specificationVarArgsIndex; this.implicit = parameter.implicit; this.localName = parameter.localName; - this.varArgsIndex = parameter.varArgsIndex; + this.typeVarArgsIndex = parameter.typeVarArgsIndex; } - public int getVarArgsIndex() { - return varArgsIndex; + public int getTypeVarArgsIndex() { + return typeVarArgsIndex; } public boolean isImplicit() { return implicit; } - public int getSpecificationIndex() { - return specificationIndex; + public int getSpecificationVarArgsIndex() { + return specificationVarArgsIndex; } public String getLocalName() { @@ -102,15 +102,15 @@ } public TypeMirror getType() { - return type; + return actualType; } public TypeData getTypeSystemType() { return typeSystemType; } - public boolean isVarArgs() { - return varArgsIndex >= 0; + public boolean isTypeVarArgs() { + return typeVarArgsIndex >= 0; } public ActualParameter getPreviousParameter() { @@ -119,6 +119,6 @@ @Override public String toString() { - return Utils.getSimpleName(type); + return Utils.getSimpleName(actualType); } } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MessageContainer.java Tue Jan 07 12:22:47 2014 +0100 @@ -64,8 +64,8 @@ } verifyExpectedMessages(context, log, childMessages); - for (Message message : getMessages()) { - emitDefault(context, baseElement, log, message); + for (int i = getMessages().size() - 1; i >= 0; i--) { + emitDefault(context, baseElement, log, getMessages().get(i)); } for (MessageContainer sink : findChildContainers()) { diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/MethodSpec.java Tue Jan 07 12:22:47 2014 +0100 @@ -27,7 +27,6 @@ import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.node.NodeChildData.*; public class MethodSpec { @@ -37,34 +36,36 @@ private final List optional = new ArrayList<>(); private final List required = new ArrayList<>(); - private int minimumRequiredArguments; - private boolean variableRequiredArguments; + private boolean ignoreAdditionalParameters; + private boolean ignoreAdditionalSpecifications; + private boolean variableRequiredParameters; + private List typeDefinitions; public MethodSpec(ParameterSpec returnType) { this.returnType = returnType; } - public void setMinimumRequiredArguments(int minimumRequiredArguments) { - this.minimumRequiredArguments = minimumRequiredArguments; + public void setVariableRequiredParameters(boolean variableRequiredParameters) { + this.variableRequiredParameters = variableRequiredParameters; } - public int getMinimumRequiredArguments() { - return minimumRequiredArguments; - } - - public void setVariableRequiredArguments(boolean variableArguments) { - this.variableRequiredArguments = variableArguments; - } - - public boolean isVariableRequiredArguments() { - return variableRequiredArguments; + public boolean isVariableRequiredParameters() { + return variableRequiredParameters; } public void addImplicitRequiredType(TypeMirror type) { this.implicitRequiredTypes.add(type); } + public void setIgnoreAdditionalParameters(boolean ignoreAdditionalParameter) { + this.ignoreAdditionalParameters = ignoreAdditionalParameter; + } + + public boolean isIgnoreAdditionalParameters() { + return ignoreAdditionalParameters; + } + public void addOptional(ParameterSpec spec) { optional.add(spec); } @@ -158,15 +159,18 @@ sep = ", "; } - for (ParameterSpec requiredSpec : getRequired()) { + for (int i = 0; i < getRequired().size(); i++) { + ParameterSpec requiredSpec = getRequired().get(i); b.append(sep); - if (requiredSpec.getCardinality() == Cardinality.MANY) { - b.append("{"); + + if (isVariableRequiredParameters() && i == getRequired().size() - 1) { + b.append(("{")); } b.append(createTypeSignature(requiredSpec, false)); - if (requiredSpec.getCardinality() == Cardinality.MANY) { - b.append("}"); + if (isVariableRequiredParameters() && i == getRequired().size() - 1) { + b.append(("}")); } + sep = ", "; } @@ -234,4 +238,12 @@ } } + public void setIgnoreAdditionalSpecifications(boolean ignoreAdditoinalSpecifications) { + this.ignoreAdditionalSpecifications = ignoreAdditoinalSpecifications; + } + + public boolean isIgnoreAdditionalSpecifications() { + return ignoreAdditionalSpecifications; + } + } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/ParameterSpec.java Tue Jan 07 12:22:47 2014 +0100 @@ -27,44 +27,46 @@ import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.node.NodeChildData.*; -import com.oracle.truffle.dsl.processor.template.MethodSpec.*; +import com.oracle.truffle.dsl.processor.node.*; +import com.oracle.truffle.dsl.processor.template.MethodSpec.TypeDef; public class ParameterSpec { private final String name; private final List allowedTypes; - /** Cardinality one or multiple. */ - private Cardinality cardinality = Cardinality.ONE; - /** Type is part of the method signature. Relevant for comparisons. */ - private boolean signature; - /** Type must be indexed when parsing. */ - private boolean indexed; /** Type is bound to local final variable. */ private boolean local; + /** Optional bound execution of node. */ + private NodeExecutionData execution; private TypeDef typeDefinition; - public ParameterSpec(String name, TypeMirror... allowedTypes) { - this(name, Arrays.asList(allowedTypes)); - } - public ParameterSpec(String name, List allowedTypes) { this.name = name; this.allowedTypes = allowedTypes; } + public ParameterSpec(String name, TypeMirror type) { + this(name, Arrays.asList(type)); + } + public ParameterSpec(ParameterSpec o, List allowedTypes) { this.name = o.name; - this.cardinality = o.cardinality; - this.signature = o.signature; - this.indexed = o.indexed; this.local = o.local; this.typeDefinition = o.typeDefinition; + this.execution = o.execution; this.allowedTypes = allowedTypes; } + public NodeExecutionData getExecution() { + return execution; + } + + public void setExecution(NodeExecutionData executionData) { + this.execution = executionData; + } + void setTypeDefinition(TypeDef typeDefinition) { this.typeDefinition = typeDefinition; } @@ -73,42 +75,22 @@ return typeDefinition; } - public void setSignature(boolean signature) { - this.signature = signature; - } - public void setLocal(boolean local) { this.local = local; } public boolean isSignature() { - return signature; + return execution != null; } public boolean isLocal() { return local; } - public boolean isIndexed() { - return indexed; - } - - public void setIndexed(boolean indexed) { - this.indexed = indexed; - } - - public void setCardinality(Cardinality cardinality) { - this.cardinality = cardinality; - } - public String getName() { return name; } - public Cardinality getCardinality() { - return cardinality; - } - public List getAllowedTypes() { return allowedTypes; } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethod.java Tue Jan 07 12:22:47 2014 +0100 @@ -29,6 +29,7 @@ import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.typesystem.*; +import com.oracle.truffle.dsl.processor.util.*; /** * Note: this class has a natural ordering that is inconsistent with equals. @@ -133,6 +134,14 @@ return requiredParameters; } + public Iterable getSignatureParameters() { + return new FilteredIterable<>(getParameters(), new Predicate() { + public boolean evaluate(ActualParameter value) { + return value.getSpecification().isSignature(); + } + }); + } + public List getParameters() { return parameters; } @@ -213,12 +222,10 @@ return signatureSize; } - public Signature getSignature() { - Signature signature = new Signature(); - for (ActualParameter parameter : getReturnTypeAndParameters()) { - if (!parameter.getSpecification().isSignature()) { - continue; - } + public TypeSignature getTypeSignature() { + TypeSignature signature = new TypeSignature(); + signature.types.add(getReturnType().getTypeSystemType()); + for (ActualParameter parameter : getSignatureParameters()) { TypeData typeData = parameter.getTypeSystemType(); if (typeData != null) { signature.types.add(typeData); @@ -241,7 +248,7 @@ return null; } - public void updateSignature(Signature signature) { + public void updateSignature(TypeSignature signature) { assert signature.size() >= 1; int signatureIndex = 0; for (ActualParameter parameter : getReturnTypeAndParameters()) { @@ -297,8 +304,8 @@ throw new IllegalStateException("Cannot compare two methods with different type systems."); } - List signature1 = getSignatureTypes(getReturnTypeAndParameters()); - List signature2 = getSignatureTypes(compareMethod.getReturnTypeAndParameters()); + List signature1 = getSignatureTypes(this); + List signature2 = getSignatureTypes(compareMethod); if (signature1.size() != signature2.size()) { return signature2.size() - signature1.size(); } @@ -347,25 +354,24 @@ return Utils.getSimpleName(signature1).compareTo(Utils.getSimpleName(signature2)); } - public static List getSignatureTypes(List params) { + public static List getSignatureTypes(TemplateMethod method) { List types = new ArrayList<>(); - for (ActualParameter param : params) { - if (param.getSpecification().isSignature()) { - types.add(param.getType()); - } + types.add(method.getReturnType().getType()); + for (ActualParameter param : method.getSignatureParameters()) { + types.add(param.getType()); } return types; } - public static class Signature implements Iterable, Comparable { + public static class TypeSignature implements Iterable, Comparable { final List types; - public Signature() { + public TypeSignature() { this.types = new ArrayList<>(); } - public Signature(List signature) { + public TypeSignature(List signature) { this.types = signature; } @@ -382,7 +388,7 @@ return types.get(index); } - public int compareTo(Signature other) { + public int compareTo(TypeSignature other) { if (this == other) { return 0; } else if (types.size() != other.types.size()) { @@ -404,7 +410,7 @@ return 0; } - public Signature combine(Signature genericSignature, Signature other) { + public TypeSignature combine(TypeSignature genericSignature, TypeSignature other) { assert types.size() == other.types.size(); assert genericSignature.types.size() == other.types.size(); @@ -412,7 +418,7 @@ return this; } - Signature signature = new Signature(); + TypeSignature signature = new TypeSignature(); for (int i = 0; i < types.size(); i++) { TypeData type1 = types.get(i); TypeData type2 = other.types.get(i); @@ -425,7 +431,7 @@ return signature; } - public boolean equalsParameters(Signature other) { + public boolean equalsParameters(TypeSignature other) { if (size() != other.size()) { return false; } @@ -434,8 +440,8 @@ @Override public boolean equals(Object obj) { - if (obj instanceof Signature) { - return ((Signature) obj).types.equals(types); + if (obj instanceof TypeSignature) { + return ((TypeSignature) obj).types.equals(types); } return super.equals(obj); } @@ -449,7 +455,7 @@ return types.toString(); } - public boolean hasAnyParameterMatch(Signature other) { + public boolean hasAnyParameterMatch(TypeSignature other) { for (int i = 1; i < types.size(); i++) { TypeData type1 = types.get(i); TypeData type2 = other.types.get(i); @@ -460,7 +466,7 @@ return false; } - public boolean isCompatibleTo(Signature signature) { + public boolean isCompatibleTo(TypeSignature signature) { if (size() != signature.size()) { return false; } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/template/TemplateMethodParser.java Tue Jan 07 12:22:47 2014 +0100 @@ -33,7 +33,6 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.node.NodeChildData.*; import com.oracle.truffle.dsl.processor.typesystem.*; public abstract class TemplateMethodParser { @@ -147,14 +146,23 @@ id = Utils.getAnnotationValue(String.class, idAnnotation, "value"); } - ParameterSpec returnTypeSpec = methodSpecification.getReturnType(); + TypeMirror returnType = method.getReturnType(); + List parameterTypes = new ArrayList<>(); + for (VariableElement var : method.getParameters()) { + parameterTypes.add(var.asType()); + } - ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, method.getReturnType(), template, 0, -1, false); + return parseImpl(methodSpecification, id, method, annotation, returnType, parameterTypes); + } + + private E parseImpl(MethodSpec methodSpecification, String id, ExecutableElement method, AnnotationMirror annotation, TypeMirror returnType, List parameterTypes) { + ParameterSpec returnTypeSpec = methodSpecification.getReturnType(); + ActualParameter returnTypeMirror = matchParameter(returnTypeSpec, returnType, template, -1, -1, false); if (returnTypeMirror == null) { if (emitErrors) { E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()), true); String expectedReturnType = returnTypeSpec.toSignatureString(true); - String actualReturnType = Utils.getSimpleName(method.getReturnType()); + String actualReturnType = Utils.getSimpleName(returnType); String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType, methodSpecification.toSignatureString(method.getSimpleName().toString())); @@ -165,12 +173,7 @@ } } - List parameterTypes = new ArrayList<>(); - for (VariableElement var : method.getParameters()) { - parameterTypes.add(var.asType()); - } - - List parameters = parseParameters(methodSpecification, parameterTypes, isUseVarArgs() && method.isVarArgs()); + List parameters = parseParameters(methodSpecification, parameterTypes, isUseVarArgs() && method != null ? method.isVarArgs() : false); if (parameters == null) { if (isEmitErrors()) { E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections. emptyList()), true); @@ -207,34 +210,31 @@ * Parameter parsing tries to parse required arguments starting from offset 0 with increasing * offset until it finds a signature end that matches the required specification. If there is no * end matching the required arguments, parsing fails. Parameters prior to the parsed required - * ones are cut and used to parse the optional parameters. All those remaining parameters must - * be consumed otherwise its an error. + * ones are cut and used to parse the optional parameters. */ private List parseParameters(MethodSpec spec, List parameterTypes, boolean varArgs) { List implicitTypes = spec.getImplicitRequiredTypes(); - int offset = -1; List parsedRequired = null; - ConsumableListIterator types = null; - while (parsedRequired == null && offset < parameterTypes.size()) { - offset++; - types = new ConsumableListIterator<>(new ArrayList<>(implicitTypes)); - types.data.addAll(parameterTypes.subList(offset, parameterTypes.size())); - parsedRequired = parseParametersRequired(spec, types, varArgs); + int offset = 0; + for (; offset <= parameterTypes.size(); offset++) { + List parameters = new ArrayList<>(implicitTypes); + parameters.addAll(parameterTypes.subList(offset, parameterTypes.size())); + parsedRequired = parseParametersRequired(spec, parameters, varArgs); + if (parsedRequired != null) { + break; + } } - if (parsedRequired == null && offset >= 0) { + if (parsedRequired == null) { return null; } - List potentialOptionals; - if (offset == -1) { - potentialOptionals = parameterTypes; - } else { - potentialOptionals = parameterTypes.subList(0, offset); + if (parsedRequired.isEmpty() && offset == 0) { + offset = parameterTypes.size(); } - types = new ConsumableListIterator<>(potentialOptionals); - List parsedOptionals = parseParametersOptional(spec, types); + List potentialOptionals = parameterTypes.subList(0, offset); + List parsedOptionals = parseParametersOptional(spec, potentialOptionals); if (parsedOptionals == null) { return null; } @@ -245,99 +245,105 @@ return finalParameters; } - private List parseParametersOptional(MethodSpec spec, ConsumableListIterator types) { + private List parseParametersOptional(MethodSpec spec, List types) { List parsedParams = new ArrayList<>(); - // parse optional parameters - ConsumableListIterator optionals = new ConsumableListIterator<>(spec.getOptional()); - for (TypeMirror type : types) { - int oldIndex = types.getIndex(); - int optionalCount = 1; - for (ParameterSpec paramspec : optionals) { - ActualParameter optionalParam = matchParameter(paramspec, type, template, 0, -1, false); + + int typeStartIndex = 0; + List specifications = spec.getOptional(); + outer: for (int specIndex = 0; specIndex < specifications.size(); specIndex++) { + ParameterSpec specification = specifications.get(specIndex); + for (int typeIndex = typeStartIndex; typeIndex < types.size(); typeIndex++) { + TypeMirror actualType = types.get(typeIndex); + ActualParameter optionalParam = matchParameter(specification, actualType, template, -1, -1, false); if (optionalParam != null) { - optionals.consume(optionalCount); - types.consume(); parsedParams.add(optionalParam); - break; + typeStartIndex = typeIndex + 1; + continue outer; } - optionalCount++; - } - if (oldIndex == types.getIndex()) { - // nothing found anymore skip optional - break; } } - if (types.getIndex() <= types.data.size() - 1) { + + if (typeStartIndex < types.size()) { + // not enough types found return null; } return parsedParams; } - private List parseParametersRequired(MethodSpec spec, ConsumableListIterator types, boolean varArgs) { + private List parseParametersRequired(MethodSpec spec, List types, boolean typeVarArgs) { List parsedParams = new ArrayList<>(); + List specifications = spec.getRequired(); + boolean specVarArgs = spec.isVariableRequiredParameters(); + int typeIndex = 0; + int specificationIndex = 0; - int varArgsParameterIndex = -1; - int specificationParameterIndex = 0; - ConsumableListIterator required = new ConsumableListIterator<>(spec.getRequired()); - while (required.get() != null || types.get() != null) { - if (required.get() == null || types.get() == null) { - if (required.get() != null && required.get().getCardinality() == Cardinality.MANY) { - required.consume(); - specificationParameterIndex = 0; - continue; + ParameterSpec specification; + while ((specification = nextSpecification(specifications, specificationIndex, specVarArgs)) != null) { + TypeMirror actualType = nextActualType(types, typeIndex, typeVarArgs); + if (actualType == null) { + if (spec.isIgnoreAdditionalSpecifications()) { + break; } + return null; + } + + boolean implicit = typeIndex < spec.getImplicitRequiredTypes().size(); + int typeVarArgsIndex = typeVarArgs ? typeIndex - types.size() + 1 : -1; + int specVarArgsIndex = specVarArgs ? specificationIndex - specifications.size() + 1 : -1; + + if (typeVarArgsIndex >= 0 && specVarArgsIndex >= 0) { + // both specifications and types have a variable number of arguments + // we would get into an endless loop if we would continue break; } - TypeMirror actualType = types.get(); - if (varArgs && types.isLast()) { - if (actualType.getKind() == TypeKind.ARRAY) { - actualType = ((ArrayType) actualType).getComponentType(); - } - varArgsParameterIndex++; + + ActualParameter resolvedParameter = matchParameter(specification, actualType, template, specVarArgsIndex, typeVarArgsIndex, implicit); + if (resolvedParameter == null) { + return null; } - boolean implicit = types.getIndex() < spec.getImplicitRequiredTypes().size(); - ActualParameter resolvedParameter = matchParameter(required.get(), actualType, template, specificationParameterIndex, varArgsParameterIndex, implicit); - if (resolvedParameter == null) { - if (required.get().getCardinality() == Cardinality.MANY) { - required.consume(); - continue; - } - // direct mismatch but required -> error - return null; + parsedParams.add(resolvedParameter); + typeIndex++; + specificationIndex++; + } + + if (typeIndex < types.size()) { + // additional types available + if (spec.isIgnoreAdditionalParameters()) { + return parsedParams; } else { - parsedParams.add(resolvedParameter); - - if (varArgs && types.isLast()) { - /* Both varargs spec and varargs definition. Need to consume to terminate. */ - if (required.get().getCardinality() == Cardinality.MANY) { - types.consume(); - } - } else { - types.consume(); - } - - if (required.get().getCardinality() == Cardinality.ONE) { - required.consume(); - specificationParameterIndex = 0; - } else if (required.get().getCardinality() == Cardinality.MANY) { - specificationParameterIndex++; - } + return null; } } - if (!types.toList().isEmpty() && !(varArgs && types.isLast())) { - // additional types -> error - return null; - } - - if (!required.toList().isEmpty() && !spec.isVariableRequiredArguments()) { - // additional specifications -> error - return null; - } return parsedParams; } - private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template originalTemplate, int specificationIndex, int varArgsIndex, boolean implicit) { + private static ParameterSpec nextSpecification(List specifications, int specIndex, boolean varArgs) { + if (varArgs && specIndex >= specifications.size() - 1 && !specifications.isEmpty()) { + return specifications.get(specifications.size() - 1); + } else if (specIndex < specifications.size()) { + return specifications.get(specIndex); + } else { + return null; + } + } + + private static TypeMirror nextActualType(List types, int typeIndex, boolean varArgs) { + if (varArgs && typeIndex >= types.size() - 1 && !types.isEmpty()) { + // unpack varargs array argument + TypeMirror actualType = types.get(types.size() - 1); + if (actualType.getKind() == TypeKind.ARRAY) { + actualType = ((ArrayType) actualType).getComponentType(); + } + return actualType; + } else if (typeIndex < types.size()) { + return types.get(typeIndex); + } else { + return null; + } + } + + protected final ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template originalTemplate, int specificationIndex, int varArgsIndex, boolean implicit) { TypeMirror resolvedType = mirror; if (hasError(resolvedType)) { resolvedType = context.resolveNotYetCompiledType(mirror, originalTemplate); @@ -355,57 +361,7 @@ } } - /* Helper class for parsing. */ - private static class ConsumableListIterator implements Iterable { - - private final List data; - private int index; - - public ConsumableListIterator(List data) { - this.data = data; - } - - public E get() { - if (index >= data.size()) { - return null; - } - return data.get(index); - } - - public boolean isLast() { - return index == data.size() - 1; - } - - public E consume() { - return consume(1); - } - - public E consume(int count) { - if (index + count <= data.size()) { - index += count; - return get(); - } else { - throw new ArrayIndexOutOfBoundsException(count + 1); - } - } - - public int getIndex() { - return index; - } - - @Override - public Iterator iterator() { - return toList().iterator(); - } - - public List toList() { - if (index < data.size()) { - return data.subList(index, data.size()); - } else { - return Collections. emptyList(); - } - } - + public final E create(String id, ExecutableElement methodMetadata, AnnotationMirror mirror, TypeMirror returnType, List parameterTypes) { + return parseImpl(createSpecification(methodMetadata, mirror), id, methodMetadata, mirror, returnType, parameterTypes); } - } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/GuardParser.java Tue Jan 07 12:22:47 2014 +0100 @@ -23,10 +23,8 @@ package com.oracle.truffle.dsl.processor.typesystem; import java.lang.annotation.*; -import java.util.*; import javax.lang.model.element.*; -import javax.lang.model.type.*; import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.node.*; @@ -53,16 +51,18 @@ } @Override + protected ParameterSpec createValueParameterSpec(NodeExecutionData execution) { + return super.createValueParameterSpec(execution); + } + + @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { MethodSpec spec = createDefaultMethodSpec(method, mirror, true, null); - spec.setVariableRequiredArguments(true); + spec.setIgnoreAdditionalSpecifications(true); spec.getRequired().clear(); for (ActualParameter parameter : specialization.getRequiredParameters()) { - List assignableTypes = Utils.getAssignableTypes(getContext(), parameter.getType()); - ParameterSpec paramSpec = new ParameterSpec(parameter.getLocalName(), assignableTypes); - paramSpec.setSignature(true); - spec.addRequired(paramSpec); + spec.addRequired(new ParameterSpec(parameter.getSpecification(), Utils.getAssignableTypes(getContext(), parameter.getType()))); } return spec; @@ -80,31 +80,7 @@ @Override public GuardData create(TemplateMethod method, boolean invalid) { - GuardData guard = new GuardData(method, specialization, negated); - /* - * Update parameters in way that parameter specifications match again the node field names - * etc. - */ - List newParameters = new ArrayList<>(); - for (ActualParameter parameter : guard.getParameters()) { - ActualParameter specializationParameter = specialization.findParameter(parameter.getSpecification().getName()); - if (specializationParameter == null) { - newParameters.add(parameter); - } else { - ActualParameter p; - if (parameter.getTypeSystemType() != null) { - p = new ActualParameter(specializationParameter.getSpecification(), parameter.getTypeSystemType(), specializationParameter.getSpecificationIndex(), - specializationParameter.getVarArgsIndex(), parameter.isImplicit()); - } else { - p = new ActualParameter(specializationParameter.getSpecification(), parameter.getType(), specializationParameter.getSpecificationIndex(), - specializationParameter.getVarArgsIndex(), parameter.isImplicit()); - } - newParameters.add(p); - } - } - guard.setParameters(newParameters); - - return guard; + return new GuardData(method, specialization, negated); } @Override diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java Thu Dec 26 12:37:28 2013 -0800 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/typesystem/ImplicitCastParser.java Tue Jan 07 12:22:47 2014 +0100 @@ -50,7 +50,7 @@ types.add(typeData.getPrimitiveType()); } MethodSpec spec = new MethodSpec(new ParameterSpec("target", types)); - spec.addRequired(new ParameterSpec("source", types)).setSignature(true); + spec.addRequired(new ParameterSpec("source", types)); return spec; } diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/Filterator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/Filterator.java Tue Jan 07 12:22:47 2014 +0100 @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.dsl.processor.util; + +import java.util.*; + +public class Filterator implements Iterator { + + private final Predicate includePredicate; + private final Iterator elements; + + private boolean hasCached; + private T cached; + + public Filterator(Iterator elements, Predicate includePredicate) { + this.elements = elements; + this.includePredicate = includePredicate; + } + + public boolean hasNext() { + if (hasCached) { + return true; + } + nextValue(); + return hasCached; + } + + private void nextValue() { + while (!hasCached && elements.hasNext()) { + T element = elements.next(); + if (includePredicate.evaluate(element)) { + cached = element; + hasCached = true; + } + } + } + + public T next() { + T foundCached = getCached(); + if (foundCached != null) { + return foundCached; + } else { + nextValue(); + if (!hasCached) { + throw new NoSuchElementException(); + } + return getCached(); + } + } + + private T getCached() { + if (hasCached) { + hasCached = false; + T value = cached; + cached = null; + return value; + } + return null; + } + + public void remove() { + elements.remove(); + } + +} diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/FilteredIterable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/FilteredIterable.java Tue Jan 07 12:22:47 2014 +0100 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.dsl.processor.util; + +import java.util.*; + +public class FilteredIterable implements Iterable { + + private final Iterable delegate; + private final Predicate containedPredicate; + + public FilteredIterable(Iterable delegate, Predicate containedPredicate) { + this.delegate = delegate; + this.containedPredicate = containedPredicate; + } + + public Iterator iterator() { + return new Filterator<>(delegate.iterator(), containedPredicate); + } + +} diff -r 37ec2cabf397 -r 25ecb47a6d0e graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/Predicate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/util/Predicate.java Tue Jan 07 12:22:47 2014 +0100 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.dsl.processor.util; + +public interface Predicate { + + boolean evaluate(T value); + +}