changeset 8248:c4c3f50fa9c2

Fixes for codegen builtins support.
author Christian Humer <christian.humer@gmail.com>
date Tue, 12 Mar 2013 11:37:32 +0100
parents 5b08b0f4d338
children aad7e9f4f71c
files graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeExecutableElement.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/AbstractCompiler.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionParser.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/ShortCircuitParser.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/ActualParameter.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.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/TypeData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java
diffstat 19 files changed, 236 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/GeneratedBy.java	Tue Mar 12 11:37:32 2013 +0100
@@ -25,12 +25,14 @@
 import java.lang.annotation.*;
 
 /**
- * Marks a type to be generated by another class.
+ * Marks a type to be generated by another class or a method.
  */
-@Retention(RetentionPolicy.CLASS)
+@Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.TYPE})
 public @interface GeneratedBy {
 
     Class<?> value();
 
+    String methodName() default "";
+
 }
--- a/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.api.codegen/src/com/oracle/truffle/api/codegen/NodeFactory.java	Tue Mar 12 11:37:32 2013 +0100
@@ -24,6 +24,8 @@
 
 import java.util.*;
 
+import com.oracle.truffle.api.nodes.*;
+
 /**
  * Enables the dynamic creation of generated nodes. It provides an convenient way to instantiate
  * generated node classes without using reflection.
@@ -63,4 +65,10 @@
      */
     List<List<Class<?>>> getNodeSignatures();
 
+    /**
+     * Returns a list of children that will be executed by the created node. This is useful for base
+     * nodes that can execute a variable amount of nodes.
+     */
+    List<Class<? extends Node>> getChildrenSignature();
+
 }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/Utils.java	Tue Mar 12 11:37:32 2013 +0100
@@ -55,9 +55,17 @@
         return boxedType;
     }
 
+    public static List<TypeMirror> asTypeMirrors(List<? extends Element> elements) {
+        List<TypeMirror> types = new ArrayList<>(elements.size());
+        for (Element element : elements) {
+            types.add(element.asType());
+        }
+        return types;
+    }
+
     public static List<AnnotationMirror> collectAnnotations(ProcessorContext context, AnnotationMirror markerAnnotation, String elementName, Element element,
                     Class<? extends Annotation> annotationClass) {
-        List<AnnotationMirror> result = Utils.getAnnotationValueList(markerAnnotation, elementName);
+        List<AnnotationMirror> result = Utils.getAnnotationValueList(AnnotationMirror.class, markerAnnotation, elementName);
         AnnotationMirror explicit = Utils.findAnnotationMirror(context.getEnvironment(), element, annotationClass);
         if (explicit != null) {
             result.add(explicit);
@@ -468,29 +476,32 @@
     }
 
     @SuppressWarnings("unchecked")
-    public static <T> List<T> getAnnotationValueList(AnnotationMirror mirror, String name) {
+    public static <T> List<T> getAnnotationValueList(Class<T> expectedListType, AnnotationMirror mirror, String name) {
+        List<? extends AnnotationValue> values = getAnnotationValue(List.class, mirror, name);
         List<T> result = new ArrayList<>();
-        List<? extends AnnotationValue> values = (List<? extends AnnotationValue>) getAnnotationValue(mirror, name).getValue();
+
         for (AnnotationValue value : values) {
-            result.add((T) value.getValue());
+            result.add(resolveAnnotationValue(expectedListType, value));
         }
         return result;
     }
 
-    public static TypeMirror getAnnotationValueType(AnnotationMirror mirror, String name) {
-        return (TypeMirror) getAnnotationValue(mirror, name).getValue();
+    public static <T> T getAnnotationValue(Class<T> expectedType, AnnotationMirror mirror, String name) {
+        return resolveAnnotationValue(expectedType, getAnnotationValue(mirror, name));
     }
 
-    public static TypeMirror getAnnotationValueTypeMirror(AnnotationMirror mirror, String name) {
-        return (TypeMirror) getAnnotationValue(mirror, name).getValue();
-    }
-
-    public static String getAnnotationValueString(AnnotationMirror mirror, String name) {
-        return (String) getAnnotationValue(mirror, name).getValue();
-    }
-
-    public static int getAnnotationValueInt(AnnotationMirror mirror, String name) {
-        return (int) getAnnotationValue(mirror, name).getValue();
+    @SuppressWarnings({"unchecked"})
+    private static <T> T resolveAnnotationValue(Class<T> expectedType, AnnotationValue value) {
+        Object unboxedValue = value.accept(new AnnotationValueVisitorImpl(), null);
+        if (unboxedValue != null) {
+            if (expectedType == TypeMirror.class && unboxedValue instanceof String) {
+                return null;
+            }
+            if (!expectedType.isAssignableFrom(unboxedValue.getClass())) {
+                throw new ClassCastException(unboxedValue.getClass().getName() + " not assignable from " + expectedType.getName());
+            }
+        }
+        return (T) unboxedValue;
     }
 
     public static AnnotationValue getAnnotationValue(AnnotationMirror mirror, String name) {
@@ -510,9 +521,79 @@
         if (value == null) {
             value = valueMethod.getDefaultValue();
         }
+
         return value;
     }
 
+    private static class AnnotationValueVisitorImpl extends AbstractAnnotationValueVisitor7<Object, Void> {
+
+        @Override
+        public Object visitBoolean(boolean b, Void p) {
+            return Boolean.valueOf(b);
+        }
+
+        @Override
+        public Object visitByte(byte b, Void p) {
+            return Byte.valueOf(b);
+        }
+
+        @Override
+        public Object visitChar(char c, Void p) {
+            return c;
+        }
+
+        @Override
+        public Object visitDouble(double d, Void p) {
+            return d;
+        }
+
+        @Override
+        public Object visitFloat(float f, Void p) {
+            return f;
+        }
+
+        @Override
+        public Object visitInt(int i, Void p) {
+            return i;
+        }
+
+        @Override
+        public Object visitLong(long i, Void p) {
+            return i;
+        }
+
+        @Override
+        public Object visitShort(short s, Void p) {
+            return s;
+        }
+
+        @Override
+        public Object visitString(String s, Void p) {
+            return s;
+        }
+
+        @Override
+        public Object visitType(TypeMirror t, Void p) {
+            return t;
+        }
+
+        @Override
+        public Object visitEnumConstant(VariableElement c, Void p) {
+            return c.getConstantValue();
+        }
+
+        @Override
+        public Object visitAnnotation(AnnotationMirror a, Void p) {
+            return a;
+        }
+
+        @Override
+        public Object visitArray(List<? extends AnnotationValue> vals, Void p) {
+            return vals;
+        }
+
+    }
+
     public static boolean getAnnotationValueBoolean(AnnotationMirror mirror, String name) {
         return (Boolean) getAnnotationValue(mirror, name).getValue();
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeExecutableElement.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeExecutableElement.java	Tue Mar 12 11:37:32 2013 +0100
@@ -204,7 +204,7 @@
         return v.visitExecutable(this, p);
     }
 
-    public static CodeExecutableElement clone(ProcessingEnvironment env, ExecutableElement method) {
+    public static CodeExecutableElement clone(@SuppressWarnings("unused") ProcessingEnvironment env, ExecutableElement method) {
         CodeExecutableElement copy = new CodeExecutableElement(method.getReturnType(), method.getSimpleName().toString());
         for (TypeMirror thrownType : method.getThrownTypes()) {
             copy.addThrownType(thrownType);
@@ -220,7 +220,6 @@
         for (Element element : method.getEnclosedElements()) {
             copy.add(element);
         }
-        copy.setBody(Utils.getMethodBody(env, method));
         copy.getModifiers().addAll(method.getModifiers());
         return copy;
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java	Tue Mar 12 11:37:32 2013 +0100
@@ -495,7 +495,7 @@
     }
 
     public CodeTreeBuilder create() {
-        return new CodeTreeBuilder(null);
+        return new CodeTreeBuilder(this);
     }
 
     public CodeTreeBuilder type(TypeMirror type) {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/AbstractCompiler.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/compiler/AbstractCompiler.java	Tue Mar 12 11:37:32 2013 +0100
@@ -39,6 +39,9 @@
     }
 
     protected static Object field(Object o, String fieldName) throws Exception {
+        if (o == null) {
+            return null;
+        }
         Field field = o.getClass().getField(fieldName);
         field.setAccessible(true);
         return field.get(o);
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionParser.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ext/ExtensionParser.java	Tue Mar 12 11:37:32 2013 +0100
@@ -88,7 +88,7 @@
         } else {
             AnnotationMirror foundExtension = Utils.findAnnotationMirror(context.getEnvironment(), mirror.getAnnotationType().asElement(), ExtensionAnnotation.class);
             if (foundExtension != null) {
-                String className = Utils.getAnnotationValueString(foundExtension, "processorClassName");
+                String className = Utils.getAnnotationValue(String.class, foundExtension, "processorClassName");
                 Class<?> processorClass;
                 try {
                     processorClass = Class.forName(className);
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Tue Mar 12 11:37:32 2013 +0100
@@ -34,7 +34,7 @@
 import com.oracle.truffle.api.codegen.*;
 import com.oracle.truffle.codegen.processor.*;
 import com.oracle.truffle.codegen.processor.ast.*;
-import com.oracle.truffle.codegen.processor.node.NodeFieldData.ExecutionKind;
+import com.oracle.truffle.codegen.processor.node.NodeFieldData.*;
 import com.oracle.truffle.codegen.processor.template.*;
 import com.oracle.truffle.codegen.processor.typesystem.*;
 
@@ -142,7 +142,7 @@
         return getSimpleName(operation.getTemplateType()) + "Gen";
     }
 
-    private static void startCallOperationMethod(CodeTreeBuilder body, TemplateMethod templateMethod, boolean castedValues) {
+    private void startCallOperationMethod(CodeTreeBuilder body, TemplateMethod templateMethod, boolean castedValues) {
         body.startGroup();
         ExecutableElement method = templateMethod.getMethod();
 
@@ -162,7 +162,14 @@
             } else {
                 ActualParameter parameter = templateMethod.getParameters().get(0);
                 if (castedValues) {
-                    body.string(castValueName(parameter));
+                    NodeFieldData field = node.findField(parameter.getSpecification().getName());
+                    NodeData fieldNode = field.getNodeData();
+                    ExecutableTypeData execType = fieldNode.findExecutableType(parameter.getActualTypeData(node.getTypeSystem()));
+                    if (execType.hasUnexpectedValue(getContext())) {
+                        body.string(castValueName(parameter));
+                    } else {
+                        body.string(valueName(parameter));
+                    }
                 } else {
                     body.string(valueName(parameter));
                 }
@@ -256,8 +263,7 @@
         return builder.getRoot();
     }
 
-    private static CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization,
-                    boolean onSpecialization) {
+    private CodeTree createExplicitGuards(CodeTreeBuilder parent, String conditionPrefix, SpecializationData valueSpecialization, SpecializationData guardedSpecialization, boolean onSpecialization) {
         CodeTreeBuilder builder = new CodeTreeBuilder(parent);
         String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
         if (guardedSpecialization.getGuards().length > 0) {
@@ -520,6 +526,7 @@
                 clazz.add(createCreateNodeSpecializedMethod(node));
                 clazz.add(createGetNodeClassMethod(node));
                 clazz.add(createGetNodeSignaturesMethod(node));
+                clazz.add(createGetChildrenSignatureMethod(node));
                 clazz.add(createGetInstanceMethod(node, createVisibility));
                 clazz.add(createInstanceConstant(node, clazz.asType()));
             }
@@ -570,21 +577,62 @@
             builder.startStaticCall(getContext().getType(Arrays.class), "asList");
             List<ExecutableElement> constructors = findUserConstructors(node);
             for (ExecutableElement constructor : constructors) {
-                builder.startGroup();
-                builder.type(getContext().getType(Arrays.class));
-                builder.string(".<").type(getContext().getType(Class.class)).string(">");
-                builder.startCall("asList");
-                for (VariableElement param : constructor.getParameters()) {
-                    builder.typeLiteral(param.asType());
-                }
-                builder.end();
-                builder.end();
+                builder.tree(createAsList(builder, Utils.asTypeMirrors(constructor.getParameters()), classType));
             }
             builder.end();
             builder.end();
             return method;
         }
 
+        private CodeExecutableElement createGetChildrenSignatureMethod(NodeData node) {
+            Types types = getContext().getEnvironment().getTypeUtils();
+            TypeElement listType = Utils.fromTypeMirror(getContext().getType(List.class));
+            TypeMirror classType = getContext().getType(Class.class);
+            TypeMirror nodeType = getContext().getTruffleTypes().getNode();
+            TypeMirror wildcardNodeType = types.getWildcardType(nodeType, null);
+            classType = types.getDeclaredType(Utils.fromTypeMirror(classType), wildcardNodeType);
+            TypeMirror returnType = types.getDeclaredType(listType, classType);
+
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getChildrenSignature");
+            CodeTreeBuilder builder = method.createBuilder();
+
+            List<TypeMirror> signatureTypes = new ArrayList<>();
+            assert !node.getSpecializations().isEmpty();
+            SpecializationData data = node.getSpecializations().get(0);
+            for (ActualParameter parameter : data.getParameters()) {
+                ParameterSpec spec = parameter.getSpecification();
+                NodeFieldData field = node.findField(spec.getName());
+                if (field == null) {
+                    continue;
+                }
+
+                TypeMirror type;
+                if (field.getKind() == FieldKind.CHILDREN && field.getType().getKind() == TypeKind.ARRAY) {
+                    type = ((ArrayType) field.getType()).getComponentType();
+                } else {
+                    type = field.getType();
+                }
+
+                signatureTypes.add(type);
+            }
+
+            builder.startReturn().tree(createAsList(builder, signatureTypes, classType)).end();
+            return method;
+        }
+
+        private CodeTree createAsList(CodeTreeBuilder parent, List<TypeMirror> types, TypeMirror elementClass) {
+            CodeTreeBuilder builder = parent.create();
+            builder.startGroup();
+            builder.type(getContext().getType(Arrays.class));
+            builder.string(".<").type(elementClass).string(">");
+            builder.startCall("asList");
+            for (TypeMirror typeMirror : types) {
+                builder.typeLiteral(typeMirror);
+            }
+            builder.end().end();
+            return builder.getRoot();
+        }
+
         private CodeExecutableElement createCreateNodeMethod(NodeData node) {
             CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNode");
             CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Object.class), "arguments");
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeData.java	Tue Mar 12 11:37:32 2013 +0100
@@ -51,13 +51,13 @@
     private List<ShortCircuitData> shortCircuits;
 
     public NodeData(TypeElement type, TypeSystemData typeSystem, String id) {
-        super(type, null);
+        super(type, null, null);
         this.nodeId = id;
         this.typeSystem = typeSystem;
     }
 
-    public NodeData(NodeData copy, String nodeId) {
-        super(copy.getTemplateType(), null);
+    public NodeData(NodeData copy, String templateMethodName, String nodeId) {
+        super(copy.getTemplateType(), templateMethodName, null);
         this.nodeId = nodeId;
         this.declaringNode = copy.declaringNode;
         this.declaredChildren = copy.declaredChildren;
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Tue Mar 12 11:37:32 2013 +0100
@@ -55,7 +55,7 @@
         NodeData node = null;
         try {
             parsedNodes = new HashMap<>();
-            node = parseInnerClassHierarchy((TypeElement) element);
+            node = resolveNode((TypeElement) element);
         } finally {
             parsedNodes = null;
         }
@@ -67,49 +67,45 @@
         return true;
     }
 
-    private NodeData parseInnerClassHierarchy(TypeElement rootType) {
+    private NodeData resolveNode(TypeElement rootType) {
+        String typeName = Utils.getQualifiedName(rootType);
+        if (parsedNodes.containsKey(typeName)) {
+            return parsedNodes.get(typeName);
+        }
+
         List<? extends TypeElement> types = ElementFilter.typesIn(rootType.getEnclosedElements());
+
         List<NodeData> children = new ArrayList<>();
         for (TypeElement childElement : types) {
-            NodeData childNode = parseInnerClassHierarchy(childElement);
+            NodeData childNode = resolveNode(childElement);
             if (childNode != null) {
                 children.add(childNode);
             }
         }
-        NodeData rootNode = resolveNode(rootType);
+        NodeData rootNode = parseNode(rootType);
         if (rootNode == null && children.size() > 0) {
             rootNode = new NodeData(rootType, null, rootType.getSimpleName().toString());
         }
+
+        parsedNodes.put(typeName, rootNode);
+
         if (rootNode != null) {
             children.addAll(rootNode.getDeclaredChildren());
             rootNode.setDeclaredChildren(children);
         }
 
-        return rootNode;
-    }
-
-    private NodeData resolveNode(TypeElement currentType) {
-        String typeName = Utils.getQualifiedName(currentType);
-        if (!parsedNodes.containsKey(typeName)) {
-            NodeData node = parseNode(currentType);
-            if (node != null) {
-                parsedNodes.put(typeName, node);
+        if (Log.DEBUG) {
+            NodeData parsed = parsedNodes.get(typeName);
+            if (parsed != null) {
+                String dump = parsed.dump();
+                String valid = rootNode != null ? "" : " failed";
+                String msg = String.format("Node parsing %s : %s", valid, dump);
+                log.error(msg);
+                System.out.println(msg);
             }
+        }
 
-            if (Log.DEBUG) {
-                NodeData parsed = parsedNodes.get(Utils.getQualifiedName(currentType));
-                if (parsed != null) {
-                    String dump = parsed.dump();
-                    String valid = node != null ? "" : " failed";
-                    String msg = String.format("Node parsing %s : %s", valid, dump);
-                    log.error(msg);
-                    System.out.println(msg);
-                }
-            }
-
-            return node;
-        }
-        return parsedNodes.get(typeName);
+        return rootNode;
     }
 
     private NodeData parseNode(TypeElement type) {
@@ -128,7 +124,7 @@
         boolean needsSplit;
         if (methodNodes != null) {
             needsSplit = methodNodes != null;
-            nodeType = Utils.fromTypeMirror(Utils.getAnnotationValueType(methodNodes, "value"));
+            nodeType = Utils.fromTypeMirror(Utils.getAnnotationValue(TypeMirror.class, methodNodes, "value"));
         } else {
             needsSplit = false;
             nodeType = type;
@@ -173,6 +169,7 @@
                 valid = false;
             }
         }
+
         if (!valid) {
             return null;
         }
@@ -213,7 +210,7 @@
                 nodeId = nodeId.substring(0, nodeId.length() - 4);
             }
             String newNodeId = nodeId + Utils.firstLetterUpperCase(id);
-            NodeData copy = new NodeData(node, newNodeId);
+            NodeData copy = new NodeData(node, id, newNodeId);
 
             copy.setSpecializations(specializations);
             copy.setSpecializationListeners(listeners);
@@ -221,10 +218,6 @@
             splitted.add(copy);
         }
 
-        if (splitted.isEmpty()) {
-            splitted.add(node);
-        }
-
         node.setSpecializations(new ArrayList<SpecializationData>());
         node.setSpecializationListeners(new ArrayList<SpecializationListenerData>());
 
@@ -460,18 +453,13 @@
             return null;
         }
 
-        TypeMirror typeSytemType = Utils.getAnnotationValueType(typeSystemMirror, "value");
+        TypeMirror typeSytemType = Utils.getAnnotationValue(TypeMirror.class, typeSystemMirror, "value");
         final TypeSystemData typeSystem = (TypeSystemData) context.getTemplate(typeSytemType, true);
         if (typeSystem == null) {
             log.error(templateType, "The used type system '%s' is invalid.", Utils.getQualifiedName(typeSytemType));
             return null;
         }
 
-        String nodeId = templateType.getSimpleName().toString();
-        if (nodeId.endsWith("Node") && !nodeId.equals("Node")) {
-            nodeId = nodeId.substring(0, nodeId.length() - 4);
-        }
-
         NodeData nodeData = new NodeData(templateType, typeSystem, templateType.getSimpleName().toString());
         nodeData.setNodeType(nodeType.asType());
 
@@ -479,7 +467,7 @@
 
         nodeData.setExecutableTypes(executableTypes);
 
-        parsedNodes.put(Utils.getQualifiedName(nodeType), nodeData);
+        parsedNodes.put(Utils.getQualifiedName(templateType), nodeData);
 
         List<NodeFieldData> fields = parseFields(nodeData, elements, typeHierarchy);
         if (fields == null) {
@@ -487,11 +475,6 @@
         }
         nodeData.setFields(fields);
 
-        if (!Utils.isAssignable(templateType.asType(), nodeType.asType())) {
-// nodeData.setInstanceParameterSpec(new ParameterSpec("instance", templateType.asType(), false,
-// true));
-        }
-
         return nodeData;
     }
 
@@ -626,8 +609,8 @@
         List<String> executionDefinition = null;
         if (executionOrderMirror != null) {
             executionDefinition = new ArrayList<>();
-            for (Object object : Utils.getAnnotationValueList(executionOrderMirror, "value")) {
-                executionDefinition.add((String) object);
+            for (String object : Utils.getAnnotationValueList(String.class, executionOrderMirror, "value")) {
+                executionDefinition.add(object);
             }
         }
 
@@ -635,7 +618,7 @@
         for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
             AnnotationMirror mirror = Utils.findAnnotationMirror(processingEnv, method, ShortCircuit.class);
             if (mirror != null) {
-                shortCircuits.add(Utils.getAnnotationValueString(mirror, "value"));
+                shortCircuits.add(Utils.getAnnotationValue(String.class, mirror, "value"));
             }
         }
 
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitParser.java	Tue Mar 12 11:37:32 2013 +0100
@@ -48,7 +48,7 @@
 
     @Override
     public MethodSpec createSpecification(ExecutableElement method, AnnotationMirror mirror) {
-        String shortCircuitValue = Utils.getAnnotationValueString(mirror, "value");
+        String shortCircuitValue = Utils.getAnnotationValue(String.class, mirror, "value");
 
         if (!shortCircuitValues.contains(shortCircuitValue)) {
             getContext().getLog().error(method, mirror, "Invalid short circuit value %s.", shortCircuitValue);
@@ -65,7 +65,7 @@
 
     @Override
     public ShortCircuitData create(TemplateMethod method) {
-        String shortCircuitValue = Utils.getAnnotationValueString(method.getMarkerAnnotation(), "value");
+        String shortCircuitValue = Utils.getAnnotationValue(String.class, method.getMarkerAnnotation(), "value");
         assert shortCircuitValue != null;
         assert shortCircuitValues.contains(shortCircuitValue);
         return new ShortCircuitData(method, shortCircuitValue);
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Tue Mar 12 11:37:32 2013 +0100
@@ -55,13 +55,13 @@
     }
 
     private SpecializationData parseSpecialization(TemplateMethod method) {
-        int order = Utils.getAnnotationValueInt(method.getMarkerAnnotation(), "order");
+        int order = Utils.getAnnotationValue(Integer.class, method.getMarkerAnnotation(), "order");
         if (order < 0 && order != Specialization.DEFAULT_ORDER) {
             getContext().getLog().error(method.getMethod(), method.getMarkerAnnotation(), "Invalid order attribute %d. The value must be >= 0 or the default value.");
             return null;
         }
 
-        List<TypeMirror> exceptionTypes = Utils.getAnnotationValueList(method.getMarkerAnnotation(), "rewriteOn");
+        List<TypeMirror> exceptionTypes = Utils.getAnnotationValueList(TypeMirror.class, method.getMarkerAnnotation(), "rewriteOn");
         List<SpecializationThrowsData> exceptionData = new ArrayList<>();
         for (TypeMirror exceptionType : exceptionTypes) {
             exceptionData.add(new SpecializationThrowsData(method.getMarkerAnnotation(), exceptionType));
@@ -81,7 +81,7 @@
         });
         SpecializationData specialization = new SpecializationData(method, order, exceptionData);
         boolean valid = true;
-        List<String> guardDefs = Utils.getAnnotationValueList(specialization.getMarkerAnnotation(), "guards");
+        List<String> guardDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards");
         SpecializationGuardData[] guardData = new SpecializationGuardData[guardDefs.size()];
         for (int i = 0; i < guardData.length; i++) {
             String guardMethod = guardDefs.get(i);
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java	Tue Mar 12 11:37:32 2013 +0100
@@ -33,14 +33,14 @@
     private TemplateMethod method;
     private final String name;
     private final int index;
-    private final boolean hidden;
+    private final boolean implicit;
 
-    public ActualParameter(ParameterSpec specification, TypeMirror actualType, int index, boolean hidden) {
+    public ActualParameter(ParameterSpec specification, TypeMirror actualType, int index, boolean implicit) {
         this.specification = specification;
         this.actualType = actualType;
 
         this.index = index;
-        this.hidden = hidden;
+        this.implicit = implicit;
         String valueName = specification.getName() + "Value";
         if (specification.isIndexed()) {
             valueName = valueName + index;
@@ -49,7 +49,7 @@
     }
 
     public boolean isHidden() {
-        return hidden;
+        return implicit;
     }
 
     public int getIndex() {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ClassElementFactory.java	Tue Mar 12 11:37:32 2013 +0100
@@ -128,6 +128,10 @@
 
         CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror((DeclaredType) getContext().getType(GeneratedBy.class));
         generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("value"), new CodeAnnotationValue(templateType.asType()));
+        if (model.getTemplateMethodName() != null) {
+            generatedByAnnotation.setElementValue(generatedByAnnotation.findExecutableElement("methodName"), new CodeAnnotationValue(model.getTemplateMethodName()));
+        }
+
         clazz.addAnnotationMirror(generatedByAnnotation);
 
         context.registerType(model.getTemplateType(), clazz.asType());
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/Template.java	Tue Mar 12 11:37:32 2013 +0100
@@ -32,15 +32,21 @@
 public abstract class Template {
 
     private final TypeElement templateType;
+    private final String templateMethodName;
     private final AnnotationMirror annotation;
 
     private List<? extends WritableElement> extensionElements;
 
-    public Template(TypeElement templateType, AnnotationMirror annotation) {
+    public Template(TypeElement templateType, String templateMethodName, AnnotationMirror annotation) {
         this.templateType = templateType;
+        this.templateMethodName = templateMethodName;
         this.annotation = annotation;
     }
 
+    public String getTemplateMethodName() {
+        return templateMethodName;
+    }
+
     public TypeElement getTemplateType() {
         return templateType;
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Tue Mar 12 11:37:32 2013 +0100
@@ -96,7 +96,7 @@
                 mirror = Utils.findAnnotationMirror(getContext().getEnvironment(), method, annotationType);
             }
 
-            if (method.getModifiers().contains(Modifier.PRIVATE)) {
+            if (method.getModifiers().contains(Modifier.PRIVATE) && emitErrors) {
                 getContext().getLog().error(method, "Method must not be private.");
                 valid = false;
                 continue;
@@ -160,7 +160,7 @@
         String id = method.getSimpleName().toString();
         AnnotationMirror idAnnotation = Utils.findAnnotationMirror(context.getEnvironment(), method, NodeId.class);
         if (idAnnotation != null) {
-            id = Utils.getAnnotationValueString(idAnnotation, "value");
+            id = Utils.getAnnotationValue(String.class, idAnnotation, "value");
         }
 
         return create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, parameters));
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeData.java	Tue Mar 12 11:37:32 2013 +0100
@@ -40,7 +40,7 @@
     private final List<TypeCheckData> typeChecks = new ArrayList<>();
 
     public TypeData(TypeElement templateType, AnnotationMirror annotation, TypeMirror primitiveType, TypeMirror boxedType) {
-        super(templateType, annotation);
+        super(templateType, null, annotation);
         this.primitiveType = primitiveType;
         this.boxedType = boxedType;
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemData.java	Tue Mar 12 11:37:32 2013 +0100
@@ -41,7 +41,7 @@
     private final TypeData voidType;
 
     public TypeSystemData(TypeElement templateType, AnnotationMirror annotation, TypeData[] types, TypeMirror genericType, TypeData voidType) {
-        super(templateType, annotation);
+        super(templateType, null, annotation);
         this.types = types;
         this.genericType = genericType;
         this.voidType = voidType;
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java	Wed Mar 06 18:33:52 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemParser.java	Tue Mar 12 11:37:32 2013 +0100
@@ -145,7 +145,7 @@
     }
 
     private TypeData[] parseTypes(TypeElement templateType, AnnotationMirror templateTypeAnnotation) {
-        List<TypeMirror> typeMirrors = Utils.getAnnotationValueList(templateTypeAnnotation, "value");
+        List<TypeMirror> typeMirrors = Utils.getAnnotationValueList(TypeMirror.class, templateTypeAnnotation, "value");
         if (typeMirrors.size() == 0) {
             log.error(templateType, templateTypeAnnotation, "At least one type must be defined.");
             return null;