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);
     }