Mercurial > hg > truffle
diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java @ 20984:6361fa2e3321
Truffle-DSL: further fixes for polymorphic execute signatures.
author | Christian Humer <christian.humer@oracle.com> |
---|---|
date | Wed, 15 Apr 2015 21:13:43 +0200 |
parents | 05a2b72c071f |
children | 8e5f9310f3aa |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java Wed Apr 15 21:35:51 2015 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/parser/NodeParser.java Wed Apr 15 21:13:43 2015 +0200 @@ -148,7 +148,7 @@ node.getFields().addAll(parseFields(lookupTypes, members)); node.getChildren().addAll(parseChildren(lookupTypes, members)); node.getChildExecutions().addAll(parseExecutions(node.getFields(), node.getChildren(), members)); - node.getExecutableTypes().addAll(parseExecutableTypeData(members, node.getChildExecutions().size(), context.getFrameTypes(), false)); + node.getExecutableTypes().addAll(parseExecutableTypeData(node, members, node.getSignatureSize(), context.getFrameTypes(), false)); initializeExecutableTypes(node); initializeImportGuards(node, lookupTypes, members); @@ -188,8 +188,13 @@ SpecializationData polymorphic = node.getPolymorphicSpecialization(); if (polymorphic != null) { boolean polymorphicSignatureFound = false; - TypeMirror frame = polymorphic.getFrame() != null ? polymorphic.getFrame().getType() : null; - ExecutableTypeData polymorphicType = new ExecutableTypeData(polymorphic.getReturnType().getType(), "execute", frame, TemplateMethod.getSignatureTypes(polymorphic)); + List<TypeMirror> dynamicTypes = polymorphic.getDynamicTypes(); + TypeMirror frame = null; + if (polymorphic.getFrame() != null) { + frame = dynamicTypes.remove(0); + } + + ExecutableTypeData polymorphicType = new ExecutableTypeData(node, polymorphic.getReturnType().getType(), "execute", frame, dynamicTypes); for (ExecutableTypeData type : node.getExecutableTypes()) { if (polymorphicType.sameSignature(type)) { polymorphicSignatureFound = true; @@ -214,9 +219,11 @@ } } if (!additionalAbstractRootTypes.isEmpty()) { - node.addError("Incompatible abstract execute methods found %s.", rootTypes); + node.addError("Incompatible abstract execute methods found %s.", additionalAbstractRootTypes); } + namesUnique(node.getExecutableTypes()); + } private static List<ExecutableTypeData> buildExecutableHierarchy(NodeData node) { @@ -235,7 +242,7 @@ private static void buildExecutableHierarchy(NodeData node, ExecutableTypeData parent, ListIterator<ExecutableTypeData> executesIterator) { while (executesIterator.hasNext()) { ExecutableTypeData other = executesIterator.next(); - if (other.canDelegateTo(node, parent)) { + if (other.canDelegateTo(parent)) { parent.addDelegatedFrom(other); executesIterator.remove(); } @@ -574,7 +581,7 @@ return executions; } - private List<ExecutableTypeData> parseExecutableTypeData(List<? extends Element> elements, int signatureSize, List<TypeMirror> frameTypes, boolean includeFinals) { + private List<ExecutableTypeData> parseExecutableTypeData(NodeData node, List<? extends Element> elements, int signatureSize, List<TypeMirror> frameTypes, boolean includeFinals) { List<ExecutableTypeData> typeData = new ArrayList<>(); for (ExecutableElement method : ElementFilter.methodsIn(elements)) { Set<Modifier> modifiers = method.getModifiers(); @@ -592,7 +599,7 @@ continue; } - ExecutableTypeData executableType = new ExecutableTypeData(method, signatureSize, context.getFrameTypes()); + ExecutableTypeData executableType = new ExecutableTypeData(node, method, signatureSize, context.getFrameTypes()); if (executableType.getFrameParameter() != null) { boolean supportedType = false; @@ -610,8 +617,12 @@ typeData.add(executableType); } - Collections.sort(typeData); + namesUnique(typeData); + return typeData; + } + + private static void namesUnique(List<ExecutableTypeData> typeData) { List<String> names = new ArrayList<>(); for (ExecutableTypeData type : typeData) { names.add(type.getUniqueName()); @@ -623,8 +634,6 @@ for (int i = 0; i < typeData.size(); i++) { typeData.get(i).setUniqueName(names.get(i)); } - - return typeData; } private void initializeExecutableTypes(NodeData node) { @@ -632,9 +641,7 @@ Set<String> inconsistentFrameTypes = new HashSet<>(); TypeMirror frameType = null; - Set<Integer> evaluatedCounts = new HashSet<>(); for (ExecutableTypeData execute : allExecutes) { - evaluatedCounts.add(execute.getEvaluatedCount()); TypeMirror frame = execute.getFrameParameter(); TypeMirror resolvedFrameType; @@ -788,7 +795,7 @@ if (parentNode.getFrameType() != null) { frameTypes = Arrays.asList(parentNode.getFrameType()); } - node.getExecutableTypes().addAll(parseExecutableTypeData(members, child.getExecuteWith().size(), frameTypes, true)); + node.getExecutableTypes().addAll(parseExecutableTypeData(node, members, child.getExecuteWith().size(), frameTypes, true)); node.setFrameType(parentNode.getFrameType()); return node; } @@ -1297,26 +1304,11 @@ } } - private void initializeUninitialized(final NodeData node) { + private static void initializeUninitialized(final NodeData node) { SpecializationData generic = node.getGenericSpecialization(); if (generic == null) { return; } - for (Parameter parameter : generic.getReturnTypeAndParameters()) { - if (ElementUtils.isObject(parameter.getType())) { - continue; - } - Set<String> types = new HashSet<>(); - for (SpecializationData specialization : node.getSpecializations()) { - Parameter actualParameter = specialization.findParameter(parameter.getLocalName()); - if (actualParameter != null) { - types.add(ElementUtils.getQualifiedName(actualParameter.getType())); - } - } - if (types.size() > 1) { - generic.replaceParameter(parameter.getLocalName(), new Parameter(parameter, context.getType(Object.class))); - } - } TemplateMethod uninializedMethod = new TemplateMethod("Uninitialized", -1, node, generic.getSpecification(), null, null, generic.getReturnType(), generic.getParameters()); // should not use messages from generic specialization uninializedMethod.getMessages().clear(); @@ -1329,7 +1321,6 @@ } SpecializationData generic = node.getGenericSpecialization(); - List<VariableElement> types = new ArrayList<>(); Collection<TypeMirror> frameTypes = new HashSet<>(); @@ -1338,6 +1329,10 @@ frameTypes.add(specialization.getFrame().getType()); } } + if (node.supportsFrame()) { + frameTypes.add(node.getFrameType()); + } + if (!frameTypes.isEmpty()) { frameTypes = ElementUtils.uniqueSortedTypes(frameTypes); TypeMirror frameType; @@ -1378,13 +1373,15 @@ if (usedTypes.size() == 1) { polymorphicType = usedTypes.iterator().next(); + } else { + polymorphicType = ElementUtils.getCommonSuperType(context, usedTypes); + } - if (!isReturnParameter && node.getTypeSystem().hasImplicitSourceTypes(polymorphicType)) { - polymorphicType = context.getType(Object.class); - } - } else { - polymorphicType = context.getType(Object.class); + NodeExecutionData execution = genericParameter.getSpecification().getExecution(); + if (execution != null && !ElementUtils.isSubtypeBoxed(context, polymorphicType, node.getGenericType(execution))) { + throw new AssertionError(String.format("Polymorphic types %s not compatible to generic type %s.", polymorphicType, node.getGenericType(execution))); } + } if (isReturnParameter) { returnType = polymorphicType; @@ -1395,8 +1392,11 @@ } SpecializationMethodParser parser = new SpecializationMethodParser(context, node); + SpecializationData polymorphic = parser.create("Polymorphic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, types); + if (polymorphic == null) { + throw new AssertionError("Failed to parse polymorphic signature. " + parser.createDefaultMethodSpec(null, null, false, null) + " Types: " + returnType + " - " + types); + } - SpecializationData polymorphic = parser.create("Polymorphic", TemplateMethod.NO_NATURAL_ORDER, null, null, returnType, types); polymorphic.setKind(SpecializationKind.POLYMORPHIC); node.getSpecializations().add(polymorphic); }