changeset 8310:89006c76f737

Final fields of base node can be optionally passed to builtin specialization method. And a few fixes.
author Christian Humer <christian.humer@gmail.com>
date Fri, 15 Mar 2013 21:18:33 +0100
parents 2ddf84436009
children 5663e3c7eabe
files 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/node/ExecutableTypeMethodParser.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.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/NodeFieldData.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/ShortCircuitData.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.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/MessageContainer.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.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/TypeSystemCodeGenerator.java
diffstat 15 files changed, 186 insertions(+), 145 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/ast/CodeTreeBuilder.java	Fri Mar 15 21:18:33 2013 +0100
@@ -533,7 +533,7 @@
         if (Utils.isVoid(type)) {
             tree(content);
             return this;
-        } else if (Utils.getQualifiedName(type).equals("java.lang.Object")) {
+        } else if (type.getKind() == TypeKind.DECLARED && Utils.getQualifiedName(type).equals("java.lang.Object")) {
             tree(content);
             return this;
         } else {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ExecutableTypeMethodParser.java	Fri Mar 15 21:18:33 2013 +0100
@@ -63,9 +63,6 @@
     @Override
     public ExecutableTypeData create(TemplateMethod method) {
         TypeData resolvedType = method.getReturnType().getActualTypeData(getNode().getTypeSystem());
-        if (resolvedType == null) {
-            return null;
-        }
         return new ExecutableTypeData(method, getNode().getTypeSystem(), resolvedType);
     }
 
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/MethodParser.java	Fri Mar 15 21:18:33 2013 +0100
@@ -72,6 +72,14 @@
         }
 
         for (NodeFieldData field : getNode().getFields()) {
+            if (field.getKind() == FieldKind.FIELD) {
+                ParameterSpec spec = new ParameterSpec(field.getName(), field.getType(), true);
+                spec.setLocal(true);
+                defaultParameters.add(spec);
+            }
+        }
+
+        for (NodeFieldData field : getNode().getFields()) {
             if (field.getExecutionKind() == ExecutionKind.IGNORE) {
                 continue;
             }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeCodeGenerator.java	Fri Mar 15 21:18:33 2013 +0100
@@ -68,14 +68,14 @@
     }
 
     private static String valueName(ActualParameter param) {
-        return param.getName();
+        return param.getLocalName();
     }
 
     private static String castValueName(ActualParameter parameter) {
         return valueName(parameter) + "Cast";
     }
 
-    private void addValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean includeHidden) {
+    private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame) {
         if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
             method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue"));
         }
@@ -84,7 +84,7 @@
             if (forceFrame && spec.getName().equals("frame")) {
                 continue;
             }
-            if (!includeHidden && parameter.isHidden()) {
+            if (spec.isLocal()) {
                 continue;
             }
 
@@ -92,7 +92,7 @@
         }
     }
 
-    private static void addValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeHidden) {
+    private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, boolean includeImplicit) {
         if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) {
             builder.string("frameValue");
         }
@@ -102,27 +102,84 @@
                 continue;
             }
 
-            if (!includeHidden && parameter.isHidden()) {
+            if (!includeImplicit && (parameter.isImplicit())) {
+                continue;
+            }
+            if (parameter.getSpecification().isLocal()) {
                 continue;
             }
 
-            if (unexpectedValueName != null && parameter.getName().equals(unexpectedValueName)) {
-                builder.string("ex.getResult()");
+            if (unexpectedValueName != null && parameter.getLocalName().equals(unexpectedValueName)) {
+                builder.cast(parameter.getActualType(), CodeTreeBuilder.singleString("ex.getResult()"));
             } else {
                 builder.string(valueName(parameter));
             }
         }
     }
 
-    private static void addValueParameterNamesWithCasts(CodeTreeBuilder body, SpecializationData valueSpecialization, SpecializationData targetSpecialization, boolean includeHidden) {
-        NodeData node = targetSpecialization.getNode();
+    private CodeTree createTemplateMethodCall(CodeTreeBuilder parent, TemplateMethod target, TemplateMethod sourceMethod, TemplateMethod castMethod, String unexpectedValueName) {
+        CodeTreeBuilder builder = parent.create();
+
+        boolean castedValues = sourceMethod != castMethod;
+
+        builder.startGroup();
+        ExecutableElement method = target.getMethod();
+        if (method == null) {
+            throw new IllegalStateException("Cannot call synthtetic operation methods.");
+        }
+        TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement());
+        NodeData node = (NodeData) castMethod.getTemplate();
         TypeSystemData typeSystem = node.getTypeSystem();
 
-        for (ActualParameter targetParameter : targetSpecialization.getParameters()) {
-            ActualParameter valueParameter = valueSpecialization.findParameter(targetParameter.getName());
+        boolean accessible = target.canBeAccessedByInstanceOf(node.getNodeType());
+        if (accessible) {
+            if (builder.findMethod().getModifiers().contains(STATIC)) {
+                builder.string(THIS_NODE_LOCAL_VAR_NAME);
+            } else {
+                builder.string("super");
+            }
+        } else {
+            if (method.getModifiers().contains(STATIC)) {
+                builder.type(targetClass.asType());
+            } else {
+                ActualParameter parameter = null;
+                for (ActualParameter searchParameter : target.getParameters()) {
+                    if (!searchParameter.getSpecification().isOptional()) {
+                        parameter = searchParameter;
+                        break;
+                    }
+                }
+                assert parameter != null;
+
+                if (castedValues) {
+                    NodeFieldData field = node.findField(parameter.getSpecification().getName());
+                    if (field == null) {
+                        builder.string(valueName(parameter));
+                    } else {
+                        NodeData fieldNode = field.getNodeData();
+                        ExecutableTypeData execType = fieldNode.findExecutableType(parameter.getActualTypeData(node.getTypeSystem()));
+                        if (execType.hasUnexpectedValue(getContext())) {
+                            builder.string(castValueName(parameter));
+                        } else {
+                            builder.string(valueName(parameter));
+                        }
+                    }
+                } else {
+                    builder.string(valueName(parameter));
+                }
+            }
+        }
+        builder.string(".");
+        builder.startCall(method.getSimpleName().toString());
+
+        for (ActualParameter targetParameter : castMethod.getParameters()) {
+            ActualParameter valueParameter = sourceMethod.findParameter(targetParameter.getLocalName());
+            if (valueParameter == null) {
+                continue;
+            }
             TypeData targetType = targetParameter.getActualTypeData(typeSystem);
 
-            if (!includeHidden && (targetParameter.isHidden() || valueParameter.isHidden())) {
+            if (targetParameter.isImplicit() || valueParameter.isImplicit()) {
                 continue;
             }
 
@@ -131,57 +188,33 @@
                 valueType = valueParameter.getActualTypeData(typeSystem);
             }
 
-            if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) {
-                body.string(valueName(targetParameter));
+            if (targetParameter.getSpecification().isLocal()) {
+                builder.startGroup();
+                if (builder.findMethod().getModifiers().contains(Modifier.STATIC)) {
+                    builder.string(THIS_NODE_LOCAL_VAR_NAME).string(".");
+                } else {
+                    builder.string("this.");
+                }
+                builder.string(targetParameter.getSpecification().getName());
+                builder.end();
+            } else if (unexpectedValueName != null && targetParameter.getLocalName().equals(unexpectedValueName)) {
+                builder.string("ex.getResult()");
+            } else if (targetType == null || targetType.isGeneric() || (valueType != null && valueType.equalsType(targetType))) {
+                builder.string(valueName(targetParameter));
             } else {
-                body.string(castValueName(targetParameter));
+                builder.string(castValueName(targetParameter));
             }
         }
+
+        builder.end().end();
+
+        return builder.getRoot();
     }
 
     private static String genClassName(Template operation) {
         return getSimpleName(operation.getTemplateType()) + "Gen";
     }
 
-    private void startCallOperationMethod(CodeTreeBuilder body, TemplateMethod templateMethod, boolean castedValues) {
-        body.startGroup();
-        ExecutableElement method = templateMethod.getMethod();
-        if (method == null) {
-            throw new IllegalStateException("Cannot call synthtetic operation methods.");
-        }
-        TypeElement targetClass = Utils.findNearestEnclosingType(method.getEnclosingElement());
-        NodeData node = (NodeData) templateMethod.getTemplate();
-
-        boolean accessible = templateMethod.canBeAccessedByInstanceOf(node.getNodeType());
-        if (accessible) {
-            if (body.findMethod().getModifiers().contains(STATIC)) {
-                body.string(THIS_NODE_LOCAL_VAR_NAME);
-            } else {
-                body.string("super");
-            }
-        } else {
-            if (method.getModifiers().contains(STATIC)) {
-                body.type(targetClass.asType());
-            } else {
-                ActualParameter parameter = templateMethod.getParameters().get(0);
-                if (castedValues) {
-                    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));
-                }
-            }
-        }
-        body.string(".");
-        body.startCall(method.getSimpleName().toString());
-    }
-
     private String generatedGenericMethodName(SpecializationData specialization) {
         final String prefix = "generic";
 
@@ -277,11 +310,7 @@
             for (SpecializationGuardData guard : guardedSpecialization.getGuards()) {
                 if ((guard.isOnSpecialization() && onSpecialization) || (guard.isOnExecution() && !onSpecialization)) {
                     builder.string(andOperator);
-
-                    startCallOperationMethod(builder, guard.getGuardDeclaration(), true);
-                    addValueParameterNamesWithCasts(builder, valueSpecialization, guardedSpecialization, false);
-
-                    builder.end().end(); // call
+                    builder.tree(createTemplateMethodCall(parent, guard.getGuardDeclaration(), valueSpecialization, guardedSpecialization, null));
                     andOperator = " && ";
                 }
             }
@@ -295,10 +324,10 @@
         // Implict guards based on method signature
         for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
             NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName());
-            if (field == null) {
+            if (field == null || field.getKind() == FieldKind.FIELD) {
                 continue;
             }
-            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getName());
+            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
 
             CodeTree cast = createCast(parent, field, valueParam, guardedParam);
             if (cast == null) {
@@ -316,10 +345,10 @@
         String andOperator = conditionPrefix != null ? conditionPrefix + " && " : "";
         for (ActualParameter guardedParam : guardedSpecialization.getParameters()) {
             NodeFieldData field = guardedSpecialization.getNode().findField(guardedParam.getSpecification().getName());
-            if (field == null) {
+            if (field == null || field.getKind() == FieldKind.FIELD) {
                 continue;
             }
-            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getName());
+            ActualParameter valueParam = valueSpecialization.findParameter(guardedParam.getLocalName());
 
             CodeTree implicitGuard = createImplicitGuard(builder, field, valueParam, guardedParam);
             if (implicitGuard == null) {
@@ -614,7 +643,7 @@
             for (ActualParameter parameter : data.getParameters()) {
                 ParameterSpec spec = parameter.getSpecification();
                 NodeFieldData field = node.findField(spec.getName());
-                if (field == null) {
+                if (field == null || field.getKind() == FieldKind.FIELD) {
                     continue;
                 }
 
@@ -916,7 +945,7 @@
             CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), node.getNodeType(), "specialize");
             method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
             method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "minimumState"));
-            addValueParameters(method, node.getGenericSpecialization(), false, true);
+            addInternalValueParameters(method, node.getGenericSpecialization(), false);
 
             CodeTreeBuilder body = method.createBuilder();
             body.startStatement().string("boolean allowed = (minimumState == ").string(nodeSpecializationClassName(node.getSpecializations().get(0))).string(".class)").end();
@@ -954,7 +983,7 @@
                         String methodName = generatedGenericMethodName(current);
                         CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, methodName);
                         method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
-                        addValueParameters(method, node.getGenericSpecialization(), true, true);
+                        addInternalValueParameters(method, node.getGenericSpecialization(), true);
 
                         emitGeneratedGenericSpecialization(method.createBuilder(), current, next);
 
@@ -967,7 +996,7 @@
             } else {
                 CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE, STATIC), genericReturnType, generatedGenericMethodName(null));
                 method.addParameter(new CodeVariableElement(node.getNodeType(), THIS_NODE_LOCAL_VAR_NAME));
-                addValueParameters(method, node.getGenericSpecialization(), true, true);
+                addInternalValueParameters(method, node.getGenericSpecialization(), true);
                 emitInvokeDoMethod(method.createBuilder(), node.getGenericSpecialization(), 0);
                 return Arrays.asList(method);
             }
@@ -983,7 +1012,7 @@
 
                 nextBuilder.startReturn().startCall(generatedGenericMethodName(next));
                 nextBuilder.string(THIS_NODE_LOCAL_VAR_NAME);
-                addValueParameterNames(nextBuilder, next, null, true, true);
+                addInternalValueParameterNames(nextBuilder, next, null, true, true);
                 nextBuilder.end().end();
 
                 invokeMethod = createGuardAndCast(builder, null, current.getNode().getGenericSpecialization(), current, false, invokeMethod, nextBuilder.getRoot());
@@ -1005,9 +1034,7 @@
                 emitEncounteredSynthetic(builder);
             } else {
                 builder.startReturn();
-                startCallOperationMethod(builder, specialization, true);
-                addValueParameterNamesWithCasts(builder, specialization.getNode().getGenericSpecialization(), specialization, false);
-                builder.end().end(); // start call operation
+                builder.tree(createTemplateMethodCall(builder, specialization, specialization.getNode().getGenericSpecialization(), specialization, null));
                 builder.end(); // return
             }
 
@@ -1017,7 +1044,7 @@
 
                     builder.startReturn().startCall(generatedGenericMethodName(exception.getTransitionTo()));
                     builder.string(THIS_NODE_LOCAL_VAR_NAME);
-                    addValueParameterNames(builder, exception.getTransitionTo(), null, true, true);
+                    addInternalValueParameterNames(builder, exception.getTransitionTo(), null, true, true);
                     builder.end().end();
                 }
                 builder.end();
@@ -1200,7 +1227,7 @@
                 builder.startCall(factoryClassName(node), "specialize");
                 builder.string("this");
                 builder.typeLiteral(builder.findMethod().getEnclosingElement().asType());
-                addValueParameterNames(builder, specialization, null, false, true);
+                addInternalValueParameterNames(builder, specialization, null, false, true);
                 builder.end(); // call replace, call specialize
             } else {
                 builder.startCall(factoryClassName(node), "createSpecialized").string("this").string("null").end();
@@ -1228,15 +1255,11 @@
 
                 builder.startReturn().startCall(factoryClassName(node), genericMethodName);
                 builder.string("this");
-                addValueParameterNames(builder, specialization, null, true, true);
+                addInternalValueParameterNames(builder, specialization, null, true, true);
                 builder.end().end();
             } else {
                 builder.startReturn();
-
-                startCallOperationMethod(builder, specialization, false);
-                addValueParameterNames(builder, specialization, null, false, false);
-
-                builder.end().end(); // operation call
+                builder.tree(createTemplateMethodCall(builder, specialization, specialization, specialization, null));
                 builder.end(); // return
             }
 
@@ -1255,7 +1278,7 @@
 
             for (ActualParameter parameter : specialization.getParameters()) {
                 NodeFieldData field = specialization.getNode().findField(parameter.getSpecification().getName());
-                if (field == null) {
+                if (field == null || field.getKind() == FieldKind.FIELD) {
                     continue;
                 }
 
@@ -1267,9 +1290,7 @@
         private void emitSpecializationListeners(CodeTreeBuilder builder, NodeData node) {
             for (TemplateMethod listener : node.getSpecializationListeners()) {
                 builder.startStatement();
-                startCallOperationMethod(builder, listener, false);
-                addValueParameterNames(builder, listener, null, false, false);
-                builder.end().end();
+                builder.tree(createTemplateMethodCall(builder, listener, listener, listener, null));
                 builder.end(); // statement
             }
         }
@@ -1301,12 +1322,12 @@
                 boolean execute = false;
                 for (ActualParameter exParam : generic.getParameters()) {
                     NodeFieldData exField = generic.getNode().findField(exParam.getSpecification().getName());
-                    if (exField == null) {
+                    if (exField == null || field.getKind() == FieldKind.FIELD) {
                         continue;
                     }
                     if (execute) {
                         buildFieldExecute(builder, specialization.getNode().getGenericSpecialization(), exParam, exField, param);
-                    } else if (exParam.getName().equals(param.getName())) {
+                    } else if (exParam.getLocalName().equals(param.getLocalName())) {
                         execute = true;
                     }
                 }
@@ -1365,14 +1386,12 @@
             builder.startStatement().type(shortCircuitParam.getActualType()).string(" ").string(valueName(shortCircuitParam)).string(" = ");
             ShortCircuitData shortCircuitData = specialization.getShortCircuits().get(shortCircuitIndex);
 
-            startCallOperationMethod(builder, shortCircuitData, false);
-            addValueParameterNames(builder, shortCircuitData, exceptionParam != null ? exceptionParam.getName() : null, false, false);
-            builder.end().end(); // call operation
+            builder.tree(createTemplateMethodCall(builder, shortCircuitData, shortCircuitData, shortCircuitData, exceptionParam != null ? exceptionParam.getLocalName() : null));
 
             builder.end(); // statement
 
             builder.declaration(parameter.getActualType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getActualType()));
-            builder.startIf().string(shortCircuitParam.getName()).end();
+            builder.startIf().string(shortCircuitParam.getLocalName()).end();
             builder.startBlock();
 
             return true;
@@ -1388,7 +1407,7 @@
             CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent);
             specializeCall.startCall("specializeAndExecute");
             specializeCall.string(nodeSpecializationClassName(nextSpecialization) + ".class");
-            addValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getName() : null, true, true);
+            addInternalValueParameterNames(specializeCall, nextSpecialization.getNode().getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, true);
             specializeCall.end().end();
 
             CodeTreeBuilder builder = new CodeTreeBuilder(parent);
@@ -1409,7 +1428,7 @@
             if (canThrowUnexpected) {
                 method.addThrownType(getUnexpectedValueException());
             }
-            addValueParameters(method, specialization.getNode().getGenericSpecialization(), true, true);
+            addInternalValueParameters(method, specialization.getNode().getGenericSpecialization(), true);
             clazz.add(method);
 
             CodeTreeBuilder builder = method.createBuilder();
@@ -1420,7 +1439,7 @@
             builder.startStatement();
             builder.startCall("replace");
             builder.startCall(factoryClassName(specialization.getNode()), "specialize").string("this").string("minimumState");
-            addValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false, true);
+            addInternalValueParameterNames(builder, specialization.getNode().getGenericSpecialization(), null, false, true);
             builder.end();
             builder.end(); // call replace
             builder.end(); // statement
@@ -1431,7 +1450,7 @@
             CodeTreeBuilder genericExecute = CodeTreeBuilder.createBuilder();
             genericExecute.startCall(factoryClassName(specialization.getNode()), generatedMethodName);
             genericExecute.string("this");
-            addValueParameterNames(genericExecute, specialization.getNode().getGenericSpecialization(), null, true, true);
+            addInternalValueParameterNames(genericExecute, specialization.getNode().getGenericSpecialization(), null, true, true);
             genericExecute.end(); // call generated generic
 
             CodeTree genericInvocation = createExpectType(node, returnExecutableType, genericExecute.getRoot());
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeFieldData.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeFieldData.java	Fri Mar 15 21:18:33 2013 +0100
@@ -30,7 +30,7 @@
 public class NodeFieldData extends MessageContainer {
 
     public enum FieldKind {
-        CHILD, CHILDREN
+        CHILD, CHILDREN, FIELD
     }
 
     public enum ExecutionKind {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/NodeParser.java	Fri Mar 15 21:18:33 2013 +0100
@@ -298,14 +298,14 @@
                 ParameterSpec parameterSpec = specification.findParameterSpec(specializationParameter.getSpecification().getName());
                 NodeFieldData field = node.findField(parameterSpec.getName());
                 TypeMirror actualType;
-                if (field == null) {
+                if (field == null || field.getKind() == FieldKind.FIELD) {
                     actualType = specializationParameter.getActualType();
                 } else {
                     ExecutableTypeData paramType = field.getNodeData().findAnyGenericExecutableType(context);
                     assert paramType != null;
                     actualType = paramType.getType().getPrimitiveType();
                 }
-                parameters.add(new ActualParameter(parameterSpec, actualType, specializationParameter.getIndex(), specializationParameter.isHidden()));
+                parameters.add(new ActualParameter(parameterSpec, actualType, specializationParameter.getIndex(), specializationParameter.isImplicit()));
             }
             TemplateMethod genericMethod = new TemplateMethod("Generic", node, specification, null, null, returnType, parameters);
             genericSpecialization = new SpecializationData(genericMethod, true, false);
@@ -628,9 +628,7 @@
             }
 
             NodeFieldData field = parseField(nodeData, var, shortCircuits);
-            if (field.getExecutionKind() != ExecutionKind.IGNORE) {
-                fields.add(field);
-            }
+            fields.add(field);
         }
         sortByExecutionOrder(fields, executionDefinition == null ? Collections.<String> emptyList() : executionDefinition, typeHierarchy);
         return fields;
@@ -650,32 +648,32 @@
         }
 
         AnnotationMirror mirror;
-        TypeMirror nodeType;
+        TypeMirror type;
 
         if (childMirror != null) {
             mirror = childMirror;
-            nodeType = var.asType();
+            type = var.asType();
             kind = FieldKind.CHILD;
         } else if (childrenMirror != null) {
             mirror = childrenMirror;
-            nodeType = getComponentType(var.asType());
+            type = getComponentType(var.asType());
             kind = FieldKind.CHILDREN;
         } else {
             execution = ExecutionKind.IGNORE;
-            nodeType = null;
+            type = var.asType();
             mirror = null;
-            kind = null;
+            kind = FieldKind.FIELD;
         }
 
         NodeFieldData fieldData = new NodeFieldData(var, findAccessElement(var), mirror, kind, execution);
-        if (nodeType != null) {
-            NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(nodeType));
+        if (type != null && mirror != null) {
+            NodeData fieldNodeData = resolveNode(Utils.fromTypeMirror(type));
             fieldData.setNode(fieldNodeData);
 
             if (fieldNodeData == null) {
-                fieldData.addError("Node type '%s' is invalid.", Utils.getQualifiedName(nodeType));
+                fieldData.addError("Node type '%s' is invalid.", Utils.getQualifiedName(type));
             } else if (fieldNodeData.findGenericExecutableTypes(context).isEmpty()) {
-                fieldData.addError("No executable generic types found for node '%s'.", Utils.getQualifiedName(nodeType));
+                fieldData.addError("No executable generic types found for node '%s'.", Utils.getQualifiedName(type));
             }
 
             // TODO correct handling of access elements
@@ -830,7 +828,7 @@
     private boolean isGenericShortCutMethod(NodeData node, TemplateMethod method) {
         for (ActualParameter parameter : method.getParameters()) {
             NodeFieldData field = node.findField(parameter.getSpecification().getName());
-            if (field == null) {
+            if (field == null || field.getKind() == FieldKind.FIELD) {
                 continue;
             }
             ExecutableTypeData found = null;
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitData.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/ShortCircuitData.java	Fri Mar 15 21:18:33 2013 +0100
@@ -61,7 +61,7 @@
         }
 
         for (ActualParameter param : getParameters()) {
-            ActualParameter specializationParam = specialization.findParameter(param.getName());
+            ActualParameter specializationParam = specialization.findParameter(param.getLocalName());
             if (!Utils.typeEquals(param.getActualType(), specializationParam.getActualType())) {
                 return false;
             }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationData.java	Fri Mar 15 21:18:33 2013 +0100
@@ -26,6 +26,7 @@
 
 import com.oracle.truffle.api.codegen.*;
 import com.oracle.truffle.codegen.processor.*;
+import com.oracle.truffle.codegen.processor.node.NodeFieldData.*;
 import com.oracle.truffle.codegen.processor.template.*;
 
 public class SpecializationData extends TemplateMethod {
@@ -81,7 +82,7 @@
         }
         for (ActualParameter parameter : getParameters()) {
             NodeFieldData field = getNode().findField(parameter.getSpecification().getName());
-            if (field == null) {
+            if (field == null || field.getKind() == FieldKind.FIELD) {
                 continue;
             }
             ExecutableTypeData type = field.getNodeData().findExecutableType(parameter.getActualTypeData(field.getNodeData().getTypeSystem()));
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/node/SpecializationMethodParser.java	Fri Mar 15 21:18:33 2013 +0100
@@ -80,7 +80,6 @@
             }
         });
         SpecializationData specialization = new SpecializationData(method, order, exceptionData);
-        boolean valid = true;
         AnnotationValue guardsValue = Utils.getAnnotationValue(method.getMarkerAnnotation(), "guards");
         List<String> guardDefs = Utils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards");
         List<SpecializationGuardData> guardData = new ArrayList<>(guardDefs.size());
@@ -94,15 +93,9 @@
             GuardData compatibleGuard = matchSpecializationGuard(specialization, assignedGuard);
             if (compatibleGuard != null) {
                 assignedGuard.setGuardDeclaration(compatibleGuard);
-            } else {
-                valid = false;
             }
         }
 
-        if (!valid) {
-            return null;
-        }
-
         specialization.setGuards(guardData);
 
         return specialization;
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ActualParameter.java	Fri Mar 15 21:18:33 2013 +0100
@@ -31,7 +31,7 @@
     private final ParameterSpec specification;
     private final TypeMirror actualType;
     private TemplateMethod method;
-    private final String name;
+    private final String localName;
     private final int index;
     private final boolean implicit;
 
@@ -42,13 +42,14 @@
         this.index = index;
         this.implicit = implicit;
         String valueName = specification.getName() + "Value";
+
         if (specification.isIndexed()) {
-            valueName = valueName + index;
+            valueName += index;
         }
-        this.name = valueName;
+        this.localName = valueName;
     }
 
-    public boolean isHidden() {
+    public boolean isImplicit() {
         return implicit;
     }
 
@@ -56,8 +57,8 @@
         return index;
     }
 
-    public String getName() {
-        return name;
+    public String getLocalName() {
+        return localName;
     }
 
     void setMethod(TemplateMethod method) {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MessageContainer.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/MessageContainer.java	Fri Mar 15 21:18:33 2013 +0100
@@ -67,7 +67,8 @@
     }
 
     private void emitDefault(TypeElement baseType, Log log, Message message) {
-        if (Utils.typeEquals(baseType.asType(), Utils.findRootEnclosingType(getMessageElement()).asType()) && this == message.getOriginalContainer()) {
+        TypeElement rootEnclosing = Utils.findRootEnclosingType(getMessageElement());
+        if (rootEnclosing != null && Utils.typeEquals(baseType.asType(), rootEnclosing.asType()) && this == message.getOriginalContainer()) {
             log.message(message.getKind(), getMessageElement(), getMessageAnnotation(), getMessageAnnotationValue(), message.getText());
         } else {
             MessageContainer original = message.getOriginalContainer();
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/ParameterSpec.java	Fri Mar 15 21:18:33 2013 +0100
@@ -41,6 +41,7 @@
     private final boolean optional;
     private Cardinality cardinality;
     private boolean indexed;
+    private boolean local;
 
     public ParameterSpec(String name, List<TypeMirror> allowedTypes, boolean optional, Cardinality cardinality) {
         this.allowedTypes = allowedTypes;
@@ -64,6 +65,14 @@
         this(name, nodeTypeMirrors(nodeData), optional, cardinality);
     }
 
+    public void setLocal(boolean local) {
+        this.local = local;
+    }
+
+    public boolean isLocal() {
+        return local;
+    }
+
     public boolean isIndexed() {
         return indexed;
     }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethod.java	Fri Mar 15 21:18:33 2013 +0100
@@ -102,7 +102,7 @@
 
     public ActualParameter findParameter(String valueName) {
         for (ActualParameter param : getParameters()) {
-            if (param.getName().equals(valueName)) {
+            if (param.getLocalName().equals(valueName)) {
                 return param;
             }
         }
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/template/TemplateMethodParser.java	Fri Mar 15 21:18:33 2013 +0100
@@ -159,12 +159,11 @@
         }
 
         List<TypeMirror> parameterTypes = new ArrayList<>();
-        parameterTypes.addAll(methodSpecification.getImplicitTypes());
         for (VariableElement var : method.getParameters()) {
             parameterTypes.add(var.asType());
         }
 
-        List<ActualParameter> parameters = parseParameters(parameterTypes, parameterSpecs, methodSpecification.getImplicitTypes().size());
+        List<ActualParameter> parameters = parseParameters(parameterTypes, methodSpecification.getImplicitTypes(), parameterSpecs);
         if (parameters == null) {
             if (isEmitErrors()) {
                 E invalidMethod = create(new TemplateMethod(id, template, methodSpecification, method, annotation, returnTypeMirror, Collections.<ActualParameter> emptyList()));
@@ -200,14 +199,15 @@
         return b.toString();
     }
 
-    private List<ActualParameter> parseParameters(List<TypeMirror> types, List<ParameterSpec> parameterSpecs, int hiddenCount) {
+    private List<ActualParameter> parseParameters(List<TypeMirror> types, List<TypeMirror> implicitTypes, List<ParameterSpec> parameterSpecs) {
         Iterator<? extends TypeMirror> parameterIterator = types.iterator();
+        Iterator<? extends TypeMirror> implicitParametersIterator = implicitTypes.iterator();
         Iterator<? extends ParameterSpec> specificationIterator = parameterSpecs.iterator();
 
         TypeMirror parameter = parameterIterator.hasNext() ? parameterIterator.next() : null;
+        TypeMirror implicitParameter = implicitParametersIterator.hasNext() ? implicitParametersIterator.next() : null;
         ParameterSpec specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
 
-        int globalParameterIndex = 0;
         int specificationParameterIndex = 0;
         List<ActualParameter> resolvedParameters = new ArrayList<>();
         while (parameter != null || specification != null) {
@@ -220,8 +220,20 @@
                 return null;
             }
 
-            boolean hidden = globalParameterIndex < hiddenCount;
-            ActualParameter resolvedParameter = matchParameter(specification, parameter, template, specificationParameterIndex, hidden);
+            ActualParameter resolvedParameter = null;
+
+            boolean implicit = false;
+            if (implicitParameter != null) {
+                resolvedParameter = matchParameter(specification, implicitParameter, template, specificationParameterIndex, true);
+                if (resolvedParameter != null) {
+                    implicit = true;
+                }
+            }
+
+            if (resolvedParameter == null) {
+                resolvedParameter = matchParameter(specification, parameter, template, specificationParameterIndex, false);
+            }
+
             if (resolvedParameter == null) {
                 // mismatch
                 if (specification.isOptional()) {
@@ -234,14 +246,16 @@
                 resolvedParameters.add(resolvedParameter);
 
                 // match
-                if (specification.getCardinality() == Cardinality.ONE) {
+                if (implicit) {
+                    implicitParameter = implicitParametersIterator.hasNext() ? implicitParametersIterator.next() : null;
+                } else {
                     parameter = parameterIterator.hasNext() ? parameterIterator.next() : null;
+                }
+
+                if (specification.getCardinality() == Cardinality.ONE) {
                     specification = specificationIterator.hasNext() ? specificationIterator.next() : null;
-                    globalParameterIndex++;
                     specificationParameterIndex = 0;
                 } else if (specification.getCardinality() == Cardinality.MULTIPLE) {
-                    parameter = parameterIterator.hasNext() ? parameterIterator.next() : null;
-                    globalParameterIndex++;
                     specificationParameterIndex++;
                 }
             }
@@ -249,7 +263,7 @@
         return resolvedParameters;
     }
 
-    private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template typeSystem, int index, boolean hidden) {
+    private ActualParameter matchParameter(ParameterSpec specification, TypeMirror mirror, Template typeSystem, int index, boolean implicit) {
         TypeMirror resolvedType = mirror;
         if (hasError(resolvedType)) {
             resolvedType = context.resolveNotYetCompiledType(mirror, typeSystem);
@@ -258,7 +272,7 @@
         if (!specification.matches(resolvedType)) {
             return null;
         }
-        return new ActualParameter(specification, resolvedType, index, hidden);
+        return new ActualParameter(specification, resolvedType, index, implicit);
     }
 
     protected List<TypeDef> createTypeDefinitions(ParameterSpec returnType, List<? extends ParameterSpec> parameters) {
--- a/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java	Thu Mar 14 13:13:59 2013 +0100
+++ b/graal/com.oracle.truffle.codegen.processor/src/com/oracle/truffle/codegen/processor/typesystem/TypeSystemCodeGenerator.java	Fri Mar 15 21:18:33 2013 +0100
@@ -41,15 +41,15 @@
     }
 
     public static String isTypeMethodName(TypeData type) {
-        return "is" + Utils.getSimpleName(type.getBoxedType());
+        return "is" + Utils.getTypeId(type.getBoxedType());
     }
 
     public static String asTypeMethodName(TypeData type) {
-        return "as" + Utils.getSimpleName(type.getBoxedType());
+        return "as" + Utils.getTypeId(type.getBoxedType());
     }
 
     public static String expectTypeMethodName(TypeData type) {
-        return "expect" + Utils.getSimpleName(type.getBoxedType());
+        return "expect" + Utils.getTypeId(type.getBoxedType());
     }
 
     /**