changeset 7679:5f3cba05c2fa

Cleanup and improved error messages.
author Christian Humer <christian.humer@gmail.com>
date Thu, 31 Jan 2013 16:21:46 +0100
parents 17b6a63fe7c2
children c5a4c817fe1c
files graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationValue.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java
diffstat 8 files changed, 136 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationValue.java	Thu Jan 31 11:32:14 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeAnnotationValue.java	Thu Jan 31 16:21:46 2013 +0100
@@ -31,22 +31,16 @@
 
     private final Object value;
 
-    // @formatter:off
     public CodeAnnotationValue(Object value) {
         Objects.requireNonNull(value);
-        if ((value instanceof AnnotationMirror) || (value instanceof List< ? >)
-                        || (value instanceof Boolean) || (value instanceof Byte)
-                        || (value instanceof Character) || (value instanceof Double)
-                        || (value instanceof VariableElement) || (value instanceof Float)
-                        || (value instanceof Integer) || (value instanceof Long)
-                        || (value instanceof Short) || (value instanceof String)
-                        || (value instanceof TypeMirror)) {
+        if ((value instanceof AnnotationMirror) || (value instanceof List<?>) || (value instanceof Boolean) || (value instanceof Byte) || (value instanceof Character) || (value instanceof Double) ||
+                        (value instanceof VariableElement) || (value instanceof Float) || (value instanceof Integer) || (value instanceof Long) || (value instanceof Short) ||
+                        (value instanceof String) || (value instanceof TypeMirror)) {
             this.value = value;
         } else {
             throw new IllegalArgumentException("Invalid annotation value type " + value.getClass().getName());
         }
     }
-    // @formatter:on
 
     @Override
     public Object getValue() {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java	Thu Jan 31 11:32:14 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/codewriter/AbstractCodeWriter.java	Thu Jan 31 16:21:46 2013 +0100
@@ -434,16 +434,6 @@
         }
     }
 
-    // @Override
-    // public void visitParameter(CodeVariableElement e) {
-    // for (CodeAnnotationMirror annotation : e.getAnnotationMirrors()) {
-    // annotation.accept(this);
-    // }
-    // write(typeSimpleName(e.getType()));
-    // write(" ");
-    // write(e.getSimpleName());
-    // }
-
     @Override
     public Void visitExecutable(CodeExecutableElement e, Void p) {
         for (AnnotationMirror annotation : e.getAnnotationMirrors()) {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Thu Jan 31 11:32:14 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Thu Jan 31 16:21:46 2013 +0100
@@ -653,13 +653,13 @@
             if (specialization.getExceptions().length > 0) {
                 for (SpecializationThrowsData exception : specialization.getExceptions()) {
                     builder.end().startCatchBlock(exception.getJavaClass(), "ex");
-                    buildThrowSpecialize(builder, exception.getTransitionTo(), null);
+                    buildThrowSpecialize(builder, specialization, exception.getTransitionTo(), null);
                 }
                 builder.end();
             }
             if (specialization.hasDynamicGuards()) {
                 builder.end().startElseBlock();
-                buildThrowSpecialize(builder, specialization.findNextSpecialization(), null);
+                buildThrowSpecialize(builder, specialization, specialization.findNextSpecialization(), null);
                 builder.end();
             }
         }
@@ -737,7 +737,7 @@
                         execute = true;
                     }
                 }
-                buildThrowSpecialize(builder, specialization.findNextSpecialization(), param.getSpecification());
+                buildThrowSpecialize(builder, specialization, specialization.findNextSpecialization(), param.getSpecification());
                 builder.end(); // catch block
             }
 
@@ -785,7 +785,7 @@
             }
         }
 
-        private void buildThrowSpecialize(CodeTreeBuilder builder, SpecializationData nextSpecialization, ParameterSpec exceptionSpec) {
+        private void buildThrowSpecialize(CodeTreeBuilder builder, SpecializationData currentSpecialization, SpecializationData nextSpecialization, ParameterSpec exceptionSpec) {
             boolean canThrowUnexpected = Utils.canThrowType(builder.findMethod().getThrownTypes(), getContext().getTruffleTypes().getUnexpectedValueException());
 
             CodeTreeBuilder specializeCall = CodeTreeBuilder.createBuilder();
@@ -795,10 +795,12 @@
             specializeCall.end().end();
 
             if (canThrowUnexpected) {
-                builder.startThrow();
-                builder.startNew(getContext().getTruffleTypes().getUnexpectedValueException());
+                builder.startReturn();
+                TypeData expectedType = currentSpecialization.getReturnType().getActualTypeData(currentSpecialization.getNode().getTypeSystem());
+                startCallTypeSystemMethod(context, builder, currentSpecialization.getNode(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType));
                 builder.tree(specializeCall.getRoot());
                 builder.end().end();
+                builder.end(); // return
             } else {
                 builder.startReturn();
                 builder.tree(specializeCall.getRoot());
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Thu Jan 31 11:32:14 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Thu Jan 31 16:21:46 2013 +0100
@@ -133,7 +133,8 @@
         } else {
             ExecutableTypeData execType = null;
             for (ExecutableTypeData type : types) {
-                if (!type.getReturnType().getActualTypeData(getTypeSystem()).isVoid()) {
+                TypeData returnType = type.getReturnType().getActualTypeData(getTypeSystem());
+                if (!returnType.isVoid()) {
                     if (execType != null) {
                         // multiple generic types not allowed
                         return null;
@@ -280,25 +281,12 @@
         return specializations;
     }
 
-    // @formatter:off
     public String dump() {
         StringBuilder b = new StringBuilder();
-        b.append(String.format("[name = %s\n" +
-                        "  typeSystem = %s\n" +
-                        "  fields = %s\n" +
-                        "  types = %s\n" +
-                        "  specializations = %s\n" +
-                        "  guards = %s\n" +
-                        "]", Utils.getQualifiedName(getTemplateType()),
-                            getTypeSystem(),
-                            dumpList(fields),
-                            dumpList(getExecutableTypes()),
-                            dumpList(getSpecializations()),
-                            dumpList(guards)
-                        ));
+        b.append(String.format("[name = %s\n" + "  typeSystem = %s\n" + "  fields = %s\n" + "  types = %s\n" + "  specializations = %s\n" + "  guards = %s\n" + "]",
+                        Utils.getQualifiedName(getTemplateType()), getTypeSystem(), dumpList(fields), dumpList(getExecutableTypes()), dumpList(getSpecializations()), dumpList(guards)));
         return b.toString();
     }
-    // @formatter:on
 
     private static String dumpList(Object[] array) {
         if (array == null) {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Thu Jan 31 11:32:14 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Thu Jan 31 16:21:46 2013 +0100
@@ -149,7 +149,7 @@
         nodeData.setExecutableTypes(executableTypes.toArray(new ExecutableTypeData[executableTypes.size()]));
 
         parsedNodes.put(Utils.getQualifiedName(type), nodeData); // node fields will resolve node
-                                                                 // types, to avoid endless loops
+// types, to avoid endless loops
 
         NodeFieldData[] fields = parseFields(nodeData, elements, typeHierarchy);
         if (fields == null) {
@@ -319,6 +319,19 @@
                 filteredExecutableTypes.add(t1);
             }
         }
+
+        Collections.sort(filteredExecutableTypes, new Comparator<ExecutableTypeData>() {
+
+            @Override
+            public int compare(ExecutableTypeData o1, ExecutableTypeData o2) {
+                int index1 = o1.getTypeSystem().findType(o1.getType());
+                int index2 = o2.getTypeSystem().findType(o2.getType());
+                if (index1 == -1 || index2 == -1) {
+                    return 0;
+                }
+                return index1 - index2;
+            }
+        });
         return filteredExecutableTypes;
     }
 
@@ -425,7 +438,8 @@
                 context.getLog().error(errorElement, "Node type '%s' is invalid.", Utils.getQualifiedName(nodeType));
                 return null;
             } else if (fieldNodeData.findGenericExecutableType(context) == null) {
-                context.getLog().error(errorElement, "No executable generic type found for node '%s'.", Utils.getQualifiedName(nodeType));
+                // TODO better error handling for (no or multiple?)
+                context.getLog().error(errorElement, "No or multiple executable generic types found for node '%s'.", Utils.getQualifiedName(nodeType));
                 return null;
             }
         }
@@ -684,6 +698,11 @@
                     SpecializationData targetSpecialization = specializationMap.get(throwsData.getTransitionToName());
                     AnnotationValue value = Utils.getAnnotationValue(throwsData.getAnnotationMirror(), "transitionTo");
 
+                    if (targetSpecialization != null) {
+                        log.error("Specialization throws current %s target %s compare %s.", sourceSpecialization.getMethodName(), targetSpecialization.getMethodName(),
+                                        compareSpecialization(typeSystem, sourceSpecialization, targetSpecialization));
+                    }
+
                     if (targetSpecialization == null) {
                         log.error(throwsData.getSpecialization().getMethod(), throwsData.getAnnotationMirror(), value, "Specialization with name '%s' not found.", throwsData.getTransitionToName());
                         valid = false;
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Thu Jan 31 11:32:14 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Thu Jan 31 16:21:46 2013 +0100
@@ -144,7 +144,8 @@
                 ParameterSpec spec = param.getSpecification();
                 expectedParameterSpecs.add(new ParameterSpec(spec.getName(), param.getActualType(), false));
             }
-            String expectedSignature = TemplateMethodParser.createExpectedSignature(specializationGuard.getGuardMethod(), returnTypeSpec, expectedParameterSpecs);
+            List<TypeDef> typeDefs = createTypeDefinitions(returnTypeSpec, expectedParameterSpecs);
+            String expectedSignature = TemplateMethodParser.createExpectedSignature(specializationGuard.getGuardMethod(), returnTypeSpec, expectedParameterSpecs, typeDefs);
             AnnotationValue value = Utils.getAnnotationValue(mirror, "methodName");
             getContext().getLog().error(specialization.getMethod(), mirror, value, "No guard with signature '%s' found in type system.", expectedSignature);
             return null;
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Thu Jan 31 11:32:14 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Thu Jan 31 16:21:46 2013 +0100
@@ -120,6 +120,8 @@
             return null;
         }
 
+        List<TypeDef> typeDefs = createTypeDefinitions(methodSpecification.getReturnType(), methodSpecification.getParameters());
+
         ParameterSpec returnTypeSpec = methodSpecification.getReturnType();
         List<ParameterSpec> parameterSpecs = new ArrayList<>();
         parameterSpecs.addAll(methodSpecification.getParameters());
@@ -127,11 +129,11 @@
         ActualParameter returnTypeMirror = resolveTypeMirror(returnTypeSpec, method.getReturnType(), template);
         if (returnTypeMirror == null) {
             if (isEmitErrors()) {
-                String expectedReturnType = createTypeSignature(returnTypeSpec, true);
+                String expectedReturnType = createTypeSignature(returnTypeSpec, typeDefs, true);
                 String actualReturnType = Utils.getSimpleName(method.getReturnType());
 
                 String message = String.format("The provided return type \"%s\" does not match expected return type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
-                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
 
                 context.getLog().error(method, annotation, message);
             }
@@ -160,10 +162,10 @@
                 } else if (!specification.isOptional()) {
                     if (isEmitErrors()) {
                         // non option type specification found -> argument missing
-                        String expectedType = createTypeSignature(specification, false);
+                        String expectedType = createTypeSignature(specification, typeDefs, false);
 
                         String message = String.format("Missing argument \"%s\".\nExpected signature: \n %s", expectedType,
-                                        createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                                        createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
 
                         context.getLog().error(method, message);
                     }
@@ -184,11 +186,11 @@
                 }
 
                 if (isEmitErrors()) {
-                    String expectedReturnType = createTypeSignature(specification, false);
+                    String expectedReturnType = createTypeSignature(specification, typeDefs, false);
                     String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
 
                     String message = String.format("The provided argument type \"%s\" does not match expected type \"%s\".\nExpected signature: \n %s", actualReturnType, expectedReturnType,
-                                    createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                                    createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
 
                     context.getLog().error(parameter, message);
                 }
@@ -208,7 +210,7 @@
             if (isEmitErrors()) {
                 String actualReturnType = Utils.getSimpleName(parameter.asType()) + " " + parameter.getSimpleName();
                 String message = String.format("No argument expected but found \"%s\".\nExpected signature: \n %s", actualReturnType,
-                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs));
+                                createExpectedSignature(method.getSimpleName().toString(), returnTypeSpec, parameterSpecs, typeDefs));
 
                 context.getLog().error(parameter, message);
             }
@@ -231,11 +233,67 @@
         return new ActualParameter(specification, resolvedType);
     }
 
-    public static String createExpectedSignature(String methodName, ParameterSpec returnType, List<? extends ParameterSpec> parameters) {
+    protected static List<TypeDef> createTypeDefinitions(ParameterSpec returnType, List<? extends ParameterSpec> parameters) {
+        List<TypeDef> typeDefs = new ArrayList<>();
+
+        TypeMirror[] types = returnType.getAllowedTypes();
+        List<ParameterSpec> allParams = new ArrayList<>();
+        allParams.add(returnType);
+        allParams.addAll(parameters);
+
+        int defIndex = 0;
+        for (ParameterSpec spec : allParams) {
+            TypeMirror[] allowedTypes = spec.getAllowedTypes();
+            if (types != null && allowedTypes.length > 1) {
+                TypeDef foundDef = null;
+                for (TypeDef def : typeDefs) {
+                    if (Arrays.equals(spec.getAllowedTypes(), def.getTypes())) {
+                        foundDef = def;
+                        break;
+                    }
+                }
+                if (foundDef == null) {
+                    foundDef = new TypeDef(types, "Types" + defIndex);
+                    typeDefs.add(foundDef);
+                    defIndex++;
+                }
+
+                foundDef.getParameters().add(spec);
+            }
+        }
+
+        return typeDefs;
+    }
+
+    protected static class TypeDef {
+
+        private final TypeMirror[] types;
+        private final String name;
+        private final List<ParameterSpec> parameters = new ArrayList<>();
+
+        public TypeDef(TypeMirror[] types, String name) {
+            this.types = types;
+            this.name = name;
+        }
+
+        public List<ParameterSpec> getParameters() {
+            return parameters;
+        }
+
+        public TypeMirror[] getTypes() {
+            return types;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
+    public static String createExpectedSignature(String methodName, ParameterSpec returnType, List<? extends ParameterSpec> parameters, List<TypeDef> typeDefs) {
         StringBuilder b = new StringBuilder();
 
         b.append("    ");
-        b.append(createTypeSignature(returnType, true));
+        b.append(createTypeSignature(returnType, typeDefs, true));
 
         b.append(" ");
         b.append(methodName);
@@ -250,7 +308,7 @@
                 b.append("{");
             }
 
-            b.append(createTypeSignature(specification, false));
+            b.append(createTypeSignature(specification, typeDefs, false));
 
             if (specification.isOptional()) {
                 b.append("]");
@@ -268,34 +326,40 @@
 
         b.append(")");
 
-        TypeMirror[] types = null;
+        if (!typeDefs.isEmpty()) {
+            b.append("\n\n");
 
-        // TODO allowed types may differ so different <Any> must be generated.
-        if (returnType.getAllowedTypes().length > 1) {
-            types = returnType.getAllowedTypes();
-        }
-        for (ParameterSpec param : parameters) {
-            if (param.getAllowedTypes().length > 1) {
-                types = param.getAllowedTypes();
+            String lineSep = "";
+            for (TypeDef def : typeDefs) {
+                b.append(lineSep);
+                b.append("    <").append(def.getName()).append(">");
+                b.append(" = {");
+                String separator = "";
+                for (TypeMirror type : def.getTypes()) {
+                    b.append(separator).append(Utils.getSimpleName(type));
+                    separator = ", ";
+                }
+                b.append("}");
+                lineSep = "\n";
+
             }
         }
-        if (types != null) {
-            b.append("\n\n    ");
-            b.append("<Any> = {");
-            String separator = "";
-            for (TypeMirror type : types) {
-                b.append(separator).append(Utils.getSimpleName(type));
-                separator = ", ";
-            }
-            b.append("}");
-        }
         return b.toString();
     }
 
-    private static String createTypeSignature(ParameterSpec spec, boolean typeOnly) {
+    private static String createTypeSignature(ParameterSpec spec, List<TypeDef> typeDefs, boolean typeOnly) {
         StringBuilder builder = new StringBuilder();
         if (spec.getAllowedTypes().length > 1) {
-            builder.append("<Any>");
+            TypeDef foundTypeDef = null;
+            for (TypeDef typeDef : typeDefs) {
+                if (typeDef.getParameters().contains(spec)) {
+                    foundTypeDef = typeDef;
+                    break;
+                }
+            }
+            if (foundTypeDef != null) {
+                builder.append("<" + foundTypeDef.getName() + ">");
+            }
         } else if (spec.getAllowedTypes().length == 1) {
             builder.append(Utils.getSimpleName(spec.getAllowedTypes()[0]));
         } else {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java	Thu Jan 31 11:32:14 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java	Thu Jan 31 16:21:46 2013 +0100
@@ -114,6 +114,10 @@
         return types[index];
     }
 
+    public int findType(TypeData typeData) {
+        return findType(typeData.getPrimitiveType());
+    }
+
     public int findType(TypeMirror type) {
         for (int i = 0; i < types.length; i++) {
             if (Utils.typeEquals(types[i].getPrimitiveType(), type)) {