# HG changeset patch # User Christian Humer # Date 1364809958 -7200 # Node ID a80bf36c6a1e311dd09d29b090c247acb93fa522 # Parent 5c58da5b823363459d7feb5d345e8e6a609e5993 Refactor to shared template method signature comparison. diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java --- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/RuntimeStringTest.java Mon Apr 01 11:52:38 2013 +0200 @@ -83,7 +83,7 @@ } @Override - Object execute() { + public Object execute() { return arguments[index]; } diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java --- a/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.api.codegen.test/src/com/oracle/truffle/api/codegen/test/TypeSystemTest.java Mon Apr 01 11:52:38 2013 +0200 @@ -50,7 +50,6 @@ } abstract Object execute(); - } @TypeSystemReference(SimpleTypes.class) diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -47,10 +47,10 @@ types.addAll(getNode().getTypeSystem().getPrimitiveTypeMirrors()); types.add(getContext().getType(void.class)); - ParameterSpec returnTypeSpec = new ParameterSpec("executedValue", types, false, Cardinality.ONE); + ParameterSpec returnTypeSpec = new ParameterSpec("executedValue", types, false, Cardinality.ONE, true); List parameters = new ArrayList<>(); - parameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true)); + parameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true, false)); return new MethodSpec(new ArrayList(), returnTypeSpec, parameters); } diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/GenericParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -51,7 +51,7 @@ for (ExecutableTypeData type : execTypes) { types.add(type.getType().getPrimitiveType()); } - return new ParameterSpec(valueName, types, false, Cardinality.ONE); + return new ParameterSpec(valueName, types, false, Cardinality.ONE, true); } @Override diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -43,7 +43,7 @@ } protected ParameterSpec createValueParameterSpec(String valueName, NodeData nodeData, boolean optional) { - return new ParameterSpec(valueName, nodeData, optional, Cardinality.ONE); + return new ParameterSpec(valueName, nodeData, optional, Cardinality.ONE, true); } protected ParameterSpec createReturnParameterSpec() { @@ -60,7 +60,7 @@ List defaultParameters = new ArrayList<>(); if (getNode().supportsFrame()) { - defaultParameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true)); + defaultParameters.add(new ParameterSpec("frame", getContext().getTruffleTypes().getFrame(), true, false)); } TypeMirror declaredType = Utils.findNearestEnclosingType(method).asType(); @@ -73,7 +73,7 @@ for (NodeFieldData field : getNode().getFields()) { if (field.getKind() == FieldKind.FIELD) { - ParameterSpec spec = new ParameterSpec(field.getName(), field.getType(), true); + ParameterSpec spec = new ParameterSpec(field.getName(), field.getType(), true, false); spec.setLocal(true); defaultParameters.add(spec); } @@ -97,7 +97,7 @@ break; } - defaultParameters.add(new ParameterSpec(shortCircuitValueName(valueName), getContext().getType(boolean.class), false)); + defaultParameters.add(new ParameterSpec(shortCircuitValueName(valueName), getContext().getType(boolean.class), false, false)); defaultParameters.add(createValueParameterSpec(valueName, field.getNodeData(), false)); } else { assert false; diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java Mon Apr 01 11:52:38 2013 +0200 @@ -262,7 +262,7 @@ CodeTreeBuilder builder = new CodeTreeBuilder(parent); CodeTree implicitGuards = createImplicitGuards(parent, conditionPrefix, valueSpecialization, guardedSpecialization); - CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, valueSpecialization, guardedSpecialization, onSpecialization); + CodeTree explicitGuards = createExplicitGuards(parent, implicitGuards == null ? conditionPrefix : null, valueSpecialization, guardedSpecialization); int ifCount = 0; @@ -302,17 +302,15 @@ return builder.getRoot(); } - private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean onSpecialization) { + private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); String andOperator = conditionPrefix != null ? conditionPrefix + " && " : ""; if (guardedSpecialization.getGuards().size() > 0) { // Explicitly specified guards - for (SpecializationGuardData guard : guardedSpecialization.getGuards()) { - if ((guard.isOnSpecialization() && onSpecialization) || (guard.isOnExecution() && !onSpecialization)) { - builder.string(andOperator); - builder.tree(createTemplateMethodCall(parent, guard.getGuardDeclaration(), valueSpecialization, guardedSpecialization, null)); - andOperator = " && "; - } + for (GuardData guard : guardedSpecialization.getGuards()) { + builder.string(andOperator); + builder.tree(createTemplateMethodCall(parent, guard, valueSpecialization, guardedSpecialization, null)); + andOperator = " && "; } } diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java Mon Apr 01 11:52:38 2013 +0200 @@ -187,22 +187,11 @@ methods.addAll(getSpecializationListeners()); methods.addAll(getExecutableTypes()); - methods.addAll(getGuards()); methods.addAll(getShortCircuits()); return methods; } - public List findGuards(String name) { - List foundGuards = new ArrayList<>(); - for (GuardData guardData : getGuards()) { - if (guardData.getMethodName().equals(name)) { - foundGuards.add(guardData); - } - } - return foundGuards; - } - public ExecutableTypeData findGenericExecutableType(ProcessorContext context, TypeData type) { List types = findGenericExecutableTypes(context); for (ExecutableTypeData availableType : types) { @@ -312,6 +301,7 @@ return null; } + @Override public TypeSystemData getTypeSystem() { return typeSystem; } @@ -334,7 +324,6 @@ dumpProperty(builder, indent, "fields", getFields()); dumpProperty(builder, indent, "executableTypes", getExecutableTypes()); dumpProperty(builder, indent, "specializations", getSpecializations()); - dumpProperty(builder, indent, "guards", getGuards()); dumpProperty(builder, indent, "messages", collectMessages()); if (getDeclaredChildren().size() > 0) { builder.append(String.format("\n%s children = [", indent)); diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -186,7 +186,7 @@ } for (NodeData splittedNode : nodes) { - finalizeSpecializations(splittedNode); + finalizeSpecializations(elements, splittedNode); verifyNode(splittedNode); } @@ -254,7 +254,6 @@ } private void parseMethods(final NodeData node, List elements) { - node.setGuards(new GuardParser(context, node, node.getTypeSystem()).parse(elements)); node.setShortCircuits(new ShortCircuitParser(context, node).parse(elements)); node.setSpecializationListeners(new SpecializationListenerParser(context, node).parse(elements)); List generics = new GenericParser(context, node).parse(elements); @@ -267,13 +266,17 @@ node.setSpecializations(allSpecializations); } - private void finalizeSpecializations(final NodeData node) { + private void finalizeSpecializations(List elements, final NodeData node) { List specializations = new ArrayList<>(node.getSpecializations()); if (specializations.isEmpty()) { return; } + for (SpecializationData specialization : specializations) { + matchGuards(elements, specialization); + } + List generics = new ArrayList<>(); for (SpecializationData spec : specializations) { if (spec.isGeneric()) { @@ -336,7 +339,7 @@ @Override public int compare(SpecializationData o1, SpecializationData o2) { - return compareSpecialization(node.getTypeSystem(), o1, o2); + return compareSpecialization(o1, o2); } }); @@ -358,6 +361,45 @@ } } + private void matchGuards(List elements, SpecializationData specialization) { + if (specialization.getGuardDefinitions().isEmpty()) { + specialization.setGuards(Collections. emptyList()); + return; + } + + List foundGuards = new ArrayList<>(); + List methods = ElementFilter.methodsIn(elements); + for (String guardDefinition : specialization.getGuardDefinitions()) { + GuardParser parser = new GuardParser(context, specialization, guardDefinition); + List guards = parser.parse(methods); + Collections.sort(guards, new Comparator() { + + @Override + public int compare(GuardData o1, GuardData o2) { + int compare = o1.compareBySignature(o2); + if (compare == 0) { + compare = o1.getId().compareTo(o2.getId()); + } + if (compare == 0) { + TypeElement enclosingType1 = Utils.findNearestEnclosingType(o1.getMethod()); + TypeElement enclosingType2 = Utils.findNearestEnclosingType(o2.getMethod()); + compare = enclosingType1.getQualifiedName().toString().compareTo(enclosingType2.getQualifiedName().toString()); + } + return compare; + } + }); + if (!guards.isEmpty()) { + foundGuards.add(guards.get(0)); + } else { + // error no guard found + specialization.addError("No guard found with with name '%s'.", guardDefinition); + } + } + + specialization.setGuards(foundGuards); + + } + private static List calculateSpecializationIds(List specializations) { int lastSize = -1; List> signatureChunks = new ArrayList<>(); @@ -927,14 +969,12 @@ } private static void verifySpecializationOrder(NodeData node) { - TypeSystemData typeSystem = node.getTypeSystem(); List specializations = node.getSpecializations(); - for (int i = 0; i < specializations.size(); i++) { SpecializationData m1 = specializations.get(i); for (int j = i + 1; j < specializations.size(); j++) { SpecializationData m2 = specializations.get(j); - int inferredOrder = compareSpecializationWithoutOrder(typeSystem, m1, m2); + int inferredOrder = compareSpecialization(m1, m2); if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) { int specOrder = m1.getOrder() - m2.getOrder(); @@ -974,70 +1014,24 @@ } } - private static int compareSpecialization(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) { - if (m1 == m2) { - return 0; - } - int result = compareSpecializationWithoutOrder(typeSystem, m1, m2); - if (result == 0) { - if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) { - return m1.getOrder() - m2.getOrder(); - } - } - return result; - } - - private static int compareSpecializationWithoutOrder(TypeSystemData typeSystem, SpecializationData m1, SpecializationData m2) { + private static int compareSpecialization(SpecializationData m1, SpecializationData m2) { if (m1 == m2) { return 0; } if (m1.getOrder() != Specialization.DEFAULT_ORDER && m2.getOrder() != Specialization.DEFAULT_ORDER) { return m1.getOrder() - m2.getOrder(); - } else if (m1.isUninitialized() && !m2.isUninitialized()) { - return -1; - } else if (!m1.isUninitialized() && m2.isUninitialized()) { - return 1; - } else if (m1.isGeneric() && !m2.isGeneric()) { - return 1; - } else if (!m1.isGeneric() && m2.isGeneric()) { - return -1; + } else if (m1.isUninitialized() ^ m2.isUninitialized()) { + return m1.isUninitialized() ? -1 : 1; + } else if (m1.isGeneric() ^ m2.isGeneric()) { + return m1.isGeneric() ? 1 : -1; } if (m1.getTemplate() != m2.getTemplate()) { throw new UnsupportedOperationException("Cannot compare two specializations with different templates."); } - int result = compareActualParameter(typeSystem, m1.getReturnType(), m2.getReturnType()); - - for (ActualParameter p1 : m1.getParameters()) { - NodeFieldData field = m1.getNode().findField(p1.getSpecification().getName()); - if (field == null) { - continue; - } - ActualParameter p2 = m2.findParameter(p1.getLocalName()); - - if (p1 != null && p2 != null && !Utils.typeEquals(p1.getActualType(), p2.getActualType())) { - int typeResult = compareActualParameter(typeSystem, p1, p2); - if (result == 0) { - result = typeResult; - } else if (Math.signum(result) != Math.signum(typeResult)) { - // We cannot define an order. - return 0; - } - } - } - return result; - } - - private static int compareActualParameter(TypeSystemData typeSystem, ActualParameter p1, ActualParameter p2) { - int index1 = typeSystem.findType(p1.getActualType()); - int index2 = typeSystem.findType(p2.getActualType()); - - assert index1 != index2; - assert !(index1 == -1 ^ index2 == -1); - - return index1 - index2; + return m1.compareBySignature(m2); } @Override diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -54,7 +54,7 @@ @Override protected ParameterSpec createReturnParameterSpec() { - return new ParameterSpec("has", getContext().getType(boolean.class), false); + return new ParameterSpec("has", getContext().getType(boolean.class), false, false); } @Override diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java Mon Apr 01 11:52:38 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.truffle.codegen.processor.*; import com.oracle.truffle.codegen.processor.node.NodeFieldData.*; import com.oracle.truffle.codegen.processor.template.*; +import com.oracle.truffle.codegen.processor.typesystem.*; public class SpecializationData extends TemplateMethod { @@ -35,7 +36,8 @@ private final boolean generic; private final boolean uninitialized; private final List exceptions; - private List guards; + private List guardDefinitions = Collections.emptyList(); + private List guards; private List shortCircuits; private boolean useSpecializationsForGeneric = true; private NodeData node; @@ -101,10 +103,14 @@ this.node = node; } - public void setGuards(List guards) { + public void setGuards(List guards) { this.guards = guards; } + public void setGuardDefinitions(List guardDefinitions) { + this.guardDefinitions = guardDefinitions; + } + public int getOrder() { return order; } @@ -121,7 +127,11 @@ return exceptions; } - public List getGuards() { + public List getGuardDefinitions() { + return guardDefinitions; + } + + public List getGuards() { return guards; } @@ -152,12 +162,7 @@ } public boolean hasDynamicGuards() { - for (SpecializationGuardData guard : getGuards()) { - if (guard.isOnExecution()) { - return true; - } - } - return false; + return !getGuards().isEmpty(); } } diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationListenerParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -43,7 +43,7 @@ @Override protected ParameterSpec createReturnParameterSpec() { - return new ParameterSpec("void", getContext().getType(void.class), false); + return new ParameterSpec("void", getContext().getType(void.class), false, false); } @Override diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -31,7 +31,6 @@ import com.oracle.truffle.api.codegen.*; import com.oracle.truffle.codegen.processor.*; import com.oracle.truffle.codegen.processor.template.*; -import com.oracle.truffle.codegen.processor.typesystem.*; public class SpecializationMethodParser extends MethodParser { @@ -54,7 +53,7 @@ return Specialization.class; } - private SpecializationData parseSpecialization(TemplateMethod method) { + private static SpecializationData parseSpecialization(TemplateMethod method) { int order = Utils.getAnnotationValue(Integer.class, method.getMarkerAnnotation(), "order"); if (order < 0 && order != Specialization.DEFAULT_ORDER) { method.addError("Invalid order attribute %d. The value must be >= 0 or the default value."); @@ -80,76 +79,10 @@ } }); SpecializationData specialization = new SpecializationData(method, order, exceptionData); - AnnotationValue guardsValue = Utils.getAnnotationValue(method.getMarkerAnnotation(), "guards"); List guardDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards"); - List guardData = new ArrayList<>(guardDefs.size()); - for (int i = 0; i < guardDefs.size(); i++) { - String guardMethod = guardDefs.get(i); - - SpecializationGuardData assignedGuard = new SpecializationGuardData(specialization, guardsValue, guardMethod, true, true); - - guardData.add(assignedGuard); - - GuardData compatibleGuard = matchSpecializationGuard(specialization, assignedGuard); - if (compatibleGuard != null) { - assignedGuard.setGuardDeclaration(compatibleGuard); - } - } - - specialization.setGuards(guardData); + specialization.setGuardDefinitions(guardDefs); return specialization; } - private GuardData matchSpecializationGuard(SpecializationData specialization, SpecializationGuardData specializationGuard) { - List foundGuards = getNode().findGuards(specializationGuard.getGuardMethod()); - - GuardData compatibleGuard = null; - for (GuardData guardData : foundGuards) { - if (isGuardCompatible(specialization, guardData)) { - compatibleGuard = guardData; - break; - } - } - - if (compatibleGuard == null) { - ParameterSpec returnTypeSpec = new ParameterSpec("returnValue", getContext().getType(boolean.class), false); - List expectedParameterSpecs = new ArrayList<>(); - - for (ActualParameter param : specialization.getParameters()) { - ParameterSpec spec = param.getSpecification(); - expectedParameterSpecs.add(new ParameterSpec(spec.getName(), param.getActualType(), false)); - } - List typeDefs = createTypeDefinitions(returnTypeSpec, expectedParameterSpecs); - String expectedSignature = TemplateMethodParser.createExpectedSignature(specializationGuard.getGuardMethod(), returnTypeSpec, expectedParameterSpecs, typeDefs); - specializationGuard.addError("No guard with signature '%s' found in type system.", expectedSignature); - } - - return compatibleGuard; - } - - private static boolean isGuardCompatible(SpecializationData specialization, GuardData guard) { - Iterator guardParameters = guard.getParameters().iterator(); - for (ActualParameter param : specialization.getParameters()) { - if (param.getSpecification().isOptional()) { - continue; - } - if (!guardParameters.hasNext()) { - return false; - } - ActualParameter guardParam = guardParameters.next(); - if (!Utils.typeEquals(guardParam.getActualType(), param.getActualType()) && !guardParam.getSpecification().isOptional()) { - return false; - } - } - while (guardParameters.hasNext()) { - ActualParameter param = guardParameters.next(); - if (!param.getSpecification().isOptional()) { - return false; - } - } - - return true; - } - } diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java Mon Apr 01 11:52:38 2013 +0200 @@ -38,37 +38,43 @@ private final String name; private final List allowedTypes; + private Cardinality cardinality; private final boolean optional; - private Cardinality cardinality; + private final boolean signature; private boolean indexed; private boolean local; - public ParameterSpec(String name, List allowedTypes, boolean optional, Cardinality cardinality) { + public ParameterSpec(String name, List allowedTypes, boolean optional, Cardinality cardinality, boolean signature) { this.allowedTypes = allowedTypes; this.name = name; this.optional = optional; this.cardinality = cardinality; + this.signature = signature; } /** Type constructor. */ - public ParameterSpec(String name, TypeMirror singleFixedType, boolean optional) { - this(name, Arrays.asList(singleFixedType), optional, Cardinality.ONE); + public ParameterSpec(String name, TypeMirror singleFixedType, boolean optional, boolean signature) { + this(name, Arrays.asList(singleFixedType), optional, Cardinality.ONE, signature); } /** Type system value constructor. */ - public ParameterSpec(String name, TypeSystemData typeSystem, boolean optional, Cardinality cardinality) { - this(name, typeSystem.getPrimitiveTypeMirrors(), optional, cardinality); + public ParameterSpec(String name, TypeSystemData typeSystem, boolean optional, Cardinality cardinality, boolean signature) { + this(name, typeSystem.getPrimitiveTypeMirrors(), optional, cardinality, signature); } /** Node value constructor. */ - public ParameterSpec(String name, NodeData nodeData, boolean optional, Cardinality cardinality) { - this(name, nodeTypeMirrors(nodeData), optional, cardinality); + public ParameterSpec(String name, NodeData nodeData, boolean optional, Cardinality cardinality, boolean signature) { + this(name, nodeTypeMirrors(nodeData), optional, cardinality, signature); } public void setLocal(boolean local) { this.local = local; } + public boolean isSignature() { + return signature; + } + public boolean isLocal() { return local; } diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java Mon Apr 01 11:52:38 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.truffle.codegen.processor.*; import com.oracle.truffle.codegen.processor.api.element.*; +import com.oracle.truffle.codegen.processor.typesystem.*; public abstract class Template extends MessageContainer { @@ -43,6 +44,8 @@ this.annotation = annotation; } + public abstract TypeSystemData getTypeSystem(); + @Override public Element getMessageElement() { return templateType; diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java Mon Apr 01 11:52:38 2013 +0200 @@ -28,6 +28,7 @@ import javax.lang.model.type.*; import com.oracle.truffle.codegen.processor.*; +import com.oracle.truffle.codegen.processor.typesystem.*; public class TemplateMethod extends MessageContainer { @@ -161,4 +162,51 @@ } return prev; } + + public List getSignature(TypeSystemData typeSystem) { + List types = new ArrayList<>(); + for (ActualParameter parameter : getReturnTypeAndParameters()) { + if (!parameter.getSpecification().isSignature()) { + continue; + } + TypeData typeData = parameter.getActualTypeData(typeSystem); + if (typeData != null) { + types.add(typeData); + } + } + return types; + } + + public int compareBySignature(TemplateMethod compareMethod) { + TypeSystemData typeSystem = getTemplate().getTypeSystem(); + if (typeSystem != compareMethod.getTemplate().getTypeSystem()) { + throw new IllegalStateException("Cannot compare two methods with different type systems."); + } + + List signature1 = getSignature(typeSystem); + List signature2 = compareMethod.getSignature(typeSystem); + if (signature1.size() != signature2.size()) { + return signature1.size() - signature2.size(); + } + + int result = 0; + for (int i = 0; i < signature1.size(); i++) { + int typeResult = compareActualParameter(typeSystem, signature1.get(i), signature2.get(i)); + if (result == 0) { + result = typeResult; + } else if (Math.signum(result) != Math.signum(typeResult)) { + // We cannot define an order. + return 0; + } + } + + return result; + } + + private static int compareActualParameter(TypeSystemData typeSystem, TypeData t1, TypeData t2) { + int index1 = typeSystem.findType(t1); + int index2 = typeSystem.findType(t2); + return index1 - index2; + } + } diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/GuardParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -29,16 +29,18 @@ import javax.lang.model.type.*; import com.oracle.truffle.codegen.processor.*; +import com.oracle.truffle.codegen.processor.node.*; import com.oracle.truffle.codegen.processor.template.*; -import com.oracle.truffle.codegen.processor.template.ParameterSpec.Cardinality; public class GuardParser extends TemplateMethodParser { - private final TypeSystemData typeSystem; + private final SpecializationData specialization; + private final String guardName; - public GuardParser(ProcessorContext context, Template template, TypeSystemData typeSystem) { - super(context, template); - this.typeSystem = typeSystem; + public GuardParser(ProcessorContext context, SpecializationData specialization, String guardName) { + super(context, specialization.getNode()); + this.specialization = specialization; + this.guardName = guardName; setEmitErrors(false); setParseNullOnError(false); } @@ -46,14 +48,16 @@ @Override public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) { List specs = new ArrayList<>(); - specs.add(new ParameterSpec("valueN", typeSystem, false, Cardinality.MULTIPLE)); - ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false); + for (ActualParameter parameter : specialization.getParameters()) { + specs.add(new ParameterSpec(parameter.getSpecification().getName(), parameter.getActualType(), true, true)); + } + ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false, false); return new MethodSpec(Collections. emptyList(), returnTypeSpec, specs); } @Override public boolean isParsable(ExecutableElement method) { - return true; + return method.getSimpleName().toString().equals(guardName); } @Override diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCastParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -46,8 +46,8 @@ return null; } List specs = new ArrayList<>(); - specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE)); - ParameterSpec returnTypeSpec = new ParameterSpec("returnType", targetType.getPrimitiveType(), false); + specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE, true)); + ParameterSpec returnTypeSpec = new ParameterSpec("returnType", targetType.getPrimitiveType(), false, true); MethodSpec spec = new MethodSpec(Collections. emptyList(), returnTypeSpec, specs); return spec; } diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeCheckParser.java Mon Apr 01 11:52:38 2013 +0200 @@ -46,8 +46,8 @@ return null; } List specs = new ArrayList<>(); - specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE)); - ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false); + specs.add(new ParameterSpec("value", getTypeSystem(), false, Cardinality.ONE, true)); + ParameterSpec returnTypeSpec = new ParameterSpec("returnType", getContext().getType(boolean.class), false, true); MethodSpec spec = new MethodSpec(Collections. emptyList(), returnTypeSpec, specs); return spec; } diff -r 5c58da5b8233 -r a80bf36c6a1e graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java --- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java Fri Mar 29 21:39:54 2013 +0100 +++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java Mon Apr 01 11:52:38 2013 +0200 @@ -43,6 +43,11 @@ super(templateType, null, annotation); } + @Override + public TypeSystemData getTypeSystem() { + return this; + } + void setTypes(List types) { this.types = types; if (types != null) {