# HG changeset patch # User Christian Humer # Date 1419892701 -3600 # Node ID f6b8787dc11309e1aaba1e8e18f8f87e6a49e448 # Parent 1acaa69ff61bcd2cff89a4fc832054e32943772a Truffle-DSL: replace complex factory system with a much simpler version diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AnnotationProcessor.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AnnotationProcessor.java Mon Dec 29 23:38:16 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/AnnotationProcessor.java Mon Dec 29 23:38:21 2014 +0100 @@ -40,11 +40,11 @@ class AnnotationProcessor { private final AbstractParser parser; - private final AbstractCompilationUnitFactory factory; + private final CodeTypeElementFactory factory; private final Set processedElements = new HashSet<>(); - public AnnotationProcessor(AbstractParser parser, AbstractCompilationUnitFactory factory) { + public AnnotationProcessor(AbstractParser parser, CodeTypeElementFactory factory) { this.parser = parser; this.factory = factory; } @@ -77,7 +77,10 @@ context.registerTemplate(type, model); if (model != null) { - CodeCompilationUnit unit = factory.process(null, model); + CodeTypeElement unit = factory.create(ProcessorContext.getInstance(), model); + if (unit == null) { + return; + } unit.setGeneratorAnnotationMirror(model.getTemplateTypeAnnotation()); unit.setGeneratorElement(model.getTemplateType()); diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/AbstractClassElementFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/AbstractClassElementFactory.java Mon Dec 29 23:38:16 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.generator; - -import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; -import static javax.lang.model.element.Modifier.*; - -import java.util.*; - -import javax.lang.model.element.*; -import javax.lang.model.type.*; -import javax.lang.model.util.*; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.dsl.processor.java.model.*; -import com.oracle.truffle.dsl.processor.model.*; - -abstract class AbstractClassElementFactory extends AbstractCodeElementFactory { - - @Override - protected abstract CodeTypeElement create(M m); - - @Override - public CodeTypeElement getElement() { - return (CodeTypeElement) super.getElement(); - } - - protected CodeExecutableElement createConstructorUsingFields(Set modifiers, CodeTypeElement clazz) { - CodeExecutableElement method = new CodeExecutableElement(modifiers, null, clazz.getSimpleName().toString()); - CodeTreeBuilder builder = method.createBuilder(); - TypeElement superClass = fromTypeMirror(clazz.getSuperclass()); - ExecutableElement constructor = findConstructor(superClass); - if (constructor != null && constructor.getParameters().size() > 0) { - builder.startStatement(); - builder.startSuperCall(); - for (VariableElement parameter : constructor.getParameters()) { - method.addParameter(new CodeVariableElement(parameter.asType(), parameter.getSimpleName().toString())); - builder.string(parameter.getSimpleName().toString()); - } - builder.end(); // super - builder.end(); // statement - } - - for (VariableElement field : clazz.getFields()) { - if (field.getModifiers().contains(STATIC)) { - continue; - } - String fieldName = field.getSimpleName().toString(); - method.addParameter(new CodeVariableElement(field.asType(), fieldName)); - builder.startStatement(); - builder.string("this."); - builder.string(fieldName); - builder.string(" = "); - if (isAssignable(field.asType(), getContext().getTruffleTypes().getNode())) { - builder.string("adoptChild(").string(fieldName).string(")"); - } else { - builder.string(fieldName); - } - builder.end(); // statement - } - - return method; - } - - private static ExecutableElement findConstructor(TypeElement clazz) { - List constructors = ElementFilter.constructorsIn(clazz.getEnclosedElements()); - if (constructors.isEmpty()) { - return null; - } else { - return constructors.get(0); - } - } - - protected CodeExecutableElement createSuperConstructor(TypeElement type, ExecutableElement element) { - if (element.getModifiers().contains(Modifier.PRIVATE)) { - return null; - } - CodeExecutableElement executable = CodeExecutableElement.clone(getContext().getEnvironment(), element); - executable.setReturnType(null); - executable.setSimpleName(CodeNames.of(type.getSimpleName().toString())); - CodeTreeBuilder b = executable.createBuilder(); - b.startStatement(); - b.startSuperCall(); - for (VariableElement v : element.getParameters()) { - b.string(v.getSimpleName().toString()); - } - b.end(); - b.end(); - - return executable; - } - - protected CodeTypeElement createClass(Template model, Set modifiers, String simpleName, TypeMirror superType, boolean enumType) { - TypeElement templateType = model.getTemplateType(); - - PackageElement pack = getContext().getEnvironment().getElementUtils().getPackageOf(templateType); - CodeTypeElement clazz = new CodeTypeElement(modifiers, enumType ? ElementKind.ENUM : ElementKind.CLASS, pack, simpleName); - TypeMirror resolvedSuperType = superType; - if (resolvedSuperType == null) { - resolvedSuperType = getContext().getType(Object.class); - } - clazz.setSuperClass(resolvedSuperType); - - 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); - return clazz; - } -} diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/AbstractCodeElementFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/AbstractCodeElementFactory.java Mon Dec 29 23:38:16 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.generator; - -import javax.lang.model.element.*; - -import com.oracle.truffle.dsl.processor.*; -import com.oracle.truffle.dsl.processor.java.model.*; - -abstract class AbstractCodeElementFactory { - - protected final ProcessorContext context; - private M model; - - private CodeElement element; - - public AbstractCodeElementFactory() { - this.context = ProcessorContext.getInstance(); - } - - protected abstract CodeElement create(M m); - - @SuppressWarnings("unused") - protected void createChildren(M m) { - } - - @SuppressWarnings({"unchecked", "rawtypes"}) - public CodeElement process(CodeElement parent, M m) { - model = m; - element = (CodeElement) create(model); - if (parent != null) { - parent.add(element); - } - if (element != null) { - createChildren(model); - } - return element; - } - - @SuppressWarnings("rawtypes") - public CodeElement getElement() { - return element; - } - - protected void add(AbstractCodeElementFactory factory, MO m) { - factory.process(this.element, m); - } - - public ProcessorContext getContext() { - return context; - } - - public M getModel() { - return model; - } - -} diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/AbstractCompilationUnitFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/AbstractCompilationUnitFactory.java Mon Dec 29 23:38:16 2014 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.dsl.processor.generator; - -import com.oracle.truffle.dsl.processor.java.model.*; - -public abstract class AbstractCompilationUnitFactory extends AbstractCodeElementFactory { - - @Override - public final CodeCompilationUnit create(M m) { - return new CodeCompilationUnit(); - } - - @SuppressWarnings("rawtypes") - @Override - public CodeCompilationUnit process(CodeElement parent, M m) { - return (CodeCompilationUnit) super.process(parent, m); - } - - @Override - protected abstract void createChildren(M m); - -} diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/CodeTypeElementFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/CodeTypeElementFactory.java Mon Dec 29 23:38:21 2014 +0100 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.dsl.processor.generator; + +import com.oracle.truffle.dsl.processor.*; +import com.oracle.truffle.dsl.processor.java.model.*; + +public abstract class CodeTypeElementFactory { + + public abstract CodeTypeElement create(ProcessorContext context, M m); + +} diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/GeneratorUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/GeneratorUtils.java Mon Dec 29 23:38:21 2014 +0100 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.dsl.processor.generator; + +import static com.oracle.truffle.dsl.processor.java.ElementUtils.*; +import static javax.lang.model.element.Modifier.*; + +import java.util.*; + +import javax.lang.model.element.*; +import javax.lang.model.type.*; +import javax.lang.model.util.*; + +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.dsl.processor.*; +import com.oracle.truffle.dsl.processor.java.model.*; +import com.oracle.truffle.dsl.processor.model.*; + +public class GeneratorUtils { + + public static CodeExecutableElement createConstructorUsingFields(ProcessorContext context, Set modifiers, CodeTypeElement clazz) { + CodeExecutableElement method = new CodeExecutableElement(modifiers, null, clazz.getSimpleName().toString()); + CodeTreeBuilder builder = method.createBuilder(); + TypeElement superClass = fromTypeMirror(clazz.getSuperclass()); + ExecutableElement constructor = findConstructor(superClass); + if (constructor != null && constructor.getParameters().size() > 0) { + builder.startStatement(); + builder.startSuperCall(); + for (VariableElement parameter : constructor.getParameters()) { + method.addParameter(new CodeVariableElement(parameter.asType(), parameter.getSimpleName().toString())); + builder.string(parameter.getSimpleName().toString()); + } + builder.end(); // super + builder.end(); // statement + } + + for (VariableElement field : clazz.getFields()) { + if (field.getModifiers().contains(STATIC)) { + continue; + } + String fieldName = field.getSimpleName().toString(); + method.addParameter(new CodeVariableElement(field.asType(), fieldName)); + builder.startStatement(); + builder.string("this."); + builder.string(fieldName); + builder.string(" = "); + if (isAssignable(field.asType(), context.getTruffleTypes().getNode())) { + builder.string("adoptChild(").string(fieldName).string(")"); + } else { + builder.string(fieldName); + } + builder.end(); // statement + } + + return method; + } + + private static ExecutableElement findConstructor(TypeElement clazz) { + List constructors = ElementFilter.constructorsIn(clazz.getEnclosedElements()); + if (constructors.isEmpty()) { + return null; + } else { + return constructors.get(0); + } + } + + public static CodeExecutableElement createSuperConstructor(ProcessorContext context, TypeElement type, ExecutableElement element) { + if (element.getModifiers().contains(Modifier.PRIVATE)) { + return null; + } + CodeExecutableElement executable = CodeExecutableElement.clone(context.getEnvironment(), element); + executable.setReturnType(null); + executable.setSimpleName(CodeNames.of(type.getSimpleName().toString())); + CodeTreeBuilder b = executable.createBuilder(); + b.startStatement(); + b.startSuperCall(); + for (VariableElement v : element.getParameters()) { + b.string(v.getSimpleName().toString()); + } + b.end(); + b.end(); + + return executable; + } + + public static CodeTypeElement createClass(Template model, Set modifiers, String simpleName, TypeMirror superType, boolean enumType) { + TypeElement templateType = model.getTemplateType(); + + ProcessorContext context = ProcessorContext.getInstance(); + + PackageElement pack = context.getEnvironment().getElementUtils().getPackageOf(templateType); + CodeTypeElement clazz = new CodeTypeElement(modifiers, enumType ? ElementKind.ENUM : ElementKind.CLASS, pack, simpleName); + TypeMirror resolvedSuperType = superType; + if (resolvedSuperType == null) { + resolvedSuperType = context.getType(Object.class); + } + clazz.setSuperClass(resolvedSuperType); + + CodeAnnotationMirror generatedByAnnotation = new CodeAnnotationMirror((DeclaredType) context.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); + return clazz; + } + +} diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeBaseFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeBaseFactory.java Mon Dec 29 23:38:16 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeBaseFactory.java Mon Dec 29 23:38:21 2014 +0100 @@ -42,7 +42,7 @@ import com.oracle.truffle.dsl.processor.parser.*; import com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard; -class NodeBaseFactory extends AbstractClassElementFactory { +class NodeBaseFactory { private static final String THIS_NODE_LOCAL_VAR_NAME = "thisNode"; @@ -60,6 +60,83 @@ static final String METADATA_FIELD_NAME = "METADATA"; + protected final ProcessorContext context; + protected final NodeData node; + protected final SpecializationData specialization; + + public NodeBaseFactory(ProcessorContext context, NodeData node, SpecializationData specialization) { + this.context = context; + this.node = node; + this.specialization = specialization; + } + + public CodeTypeElement create() { + CodeTypeElement clazz = GeneratorUtils.createClass(node, modifiers(PRIVATE, ABSTRACT, STATIC), baseClassName(node), node.getNodeType(), false); + clazz.getImplements().add(context.getTruffleTypes().getDslNode()); + + for (NodeChildData child : node.getChildren()) { + clazz.add(createChildField(child)); + + if (child.getAccessElement() != null && child.getAccessElement().getModifiers().contains(Modifier.ABSTRACT)) { + ExecutableElement getter = (ExecutableElement) child.getAccessElement(); + CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), getter); + method.getModifiers().remove(Modifier.ABSTRACT); + CodeTreeBuilder builder = method.createBuilder(); + builder.startReturn().string("this.").string(child.getName()).end(); + clazz.add(method); + } + } + + for (NodeFieldData field : node.getFields()) { + if (!field.isGenerated()) { + continue; + } + + clazz.add(new CodeVariableElement(modifiers(PROTECTED, FINAL), field.getType(), field.getName())); + if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) { + CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), field.getGetter()); + method.getModifiers().remove(Modifier.ABSTRACT); + method.createBuilder().startReturn().string("this.").string(field.getName()).end(); + clazz.add(method); + } + } + + for (String assumption : node.getAssumptions()) { + clazz.add(createAssumptionField(assumption)); + } + + createConstructors(clazz); + + SpecializationGroup rootGroup = createSpecializationGroups(node); + + if (node.needsRewrites(context)) { + if (node.isPolymorphic(context)) { + + CodeVariableElement var = new CodeVariableElement(modifiers(PROTECTED), clazz.asType(), "next0"); + var.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getTruffleTypes().getChildAnnotation())); + clazz.add(var); + + CodeExecutableElement genericCachedExecute = createCachedExecute(node.getPolymorphicSpecialization()); + clazz.add(genericCachedExecute); + + } + + for (CodeExecutableElement method : createImplicitChildrenAccessors()) { + clazz.add(method); + } + clazz.add(createInfoMessage()); + clazz.add(createMonomorphicRewrite()); + clazz.add(createCreateSpecializationMethod(rootGroup)); + } + + clazz.add(createAdoptChildren0()); + clazz.add(createGetMetadata0(true)); + clazz.add(createUpdateTypes0()); + clazz.add(createGetNext()); + + return clazz; + } + public static List findUserConstructors(TypeMirror nodeType) { List constructors = new ArrayList<>(); for (ExecutableElement constructor : ElementFilter.constructorsIn(ElementUtils.fromTypeMirror(nodeType).getEnclosedElements())) { @@ -102,85 +179,13 @@ return false; } - @Override - protected CodeTypeElement create(SpecializationData specialization) { - NodeData node = specialization.getNode(); - CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, ABSTRACT, STATIC), baseClassName(node), node.getNodeType(), false); - clazz.getImplements().add(context.getTruffleTypes().getDslNode()); - - for (NodeChildData child : node.getChildren()) { - clazz.add(createChildField(child)); - - if (child.getAccessElement() != null && child.getAccessElement().getModifiers().contains(Modifier.ABSTRACT)) { - ExecutableElement getter = (ExecutableElement) child.getAccessElement(); - CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), getter); - method.getModifiers().remove(Modifier.ABSTRACT); - CodeTreeBuilder builder = method.createBuilder(); - builder.startReturn().string("this.").string(child.getName()).end(); - clazz.add(method); - } - } - - for (NodeFieldData field : node.getFields()) { - if (!field.isGenerated()) { - continue; - } - - clazz.add(new CodeVariableElement(modifiers(PROTECTED, FINAL), field.getType(), field.getName())); - if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) { - CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), field.getGetter()); - method.getModifiers().remove(Modifier.ABSTRACT); - method.createBuilder().startReturn().string("this.").string(field.getName()).end(); - clazz.add(method); - } - } - - for (String assumption : node.getAssumptions()) { - clazz.add(createAssumptionField(assumption)); - } - - createConstructors(node, clazz); - - return clazz; - } - - @Override - protected void createChildren(SpecializationData specialization) { - NodeData node = specialization.getNode(); - CodeTypeElement clazz = getElement(); - - SpecializationGroup rootGroup = createSpecializationGroups(node); - - if (node.needsRewrites(context)) { - if (node.isPolymorphic(context)) { - - CodeVariableElement var = new CodeVariableElement(modifiers(PROTECTED), clazz.asType(), "next0"); - var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getChildAnnotation())); - clazz.add(var); - - CodeExecutableElement genericCachedExecute = createCachedExecute(node, node.getPolymorphicSpecialization()); - clazz.add(genericCachedExecute); - - } - - for (CodeExecutableElement method : createImplicitChildrenAccessors()) { - clazz.add(method); - } - clazz.add(createInfoMessage(node)); - clazz.add(createMonomorphicRewrite()); - clazz.add(createCreateSpecializationMethod(node, rootGroup)); - } - - clazz.add(createAdoptChildren0()); - clazz.add(createGetMetadata0(true)); - clazz.add(createUpdateTypes0()); - clazz.add(createGetNext()); + public SpecializationData getSpecialization() { + return specialization; } private Element createGetNext() { CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), context.getType(Node.class), "getNext0"); CodeTreeBuilder builder = method.createBuilder(); - NodeData node = getModel().getNode(); if (node.isPolymorphic(context)) { builder.startReturn().string("next0").end(); @@ -196,11 +201,11 @@ CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(void.class), "updateTypes0"); method.getParameters().add(new CodeVariableElement(classArray, "types")); - if (getModel().isPolymorphic()) { + if (getSpecialization().isPolymorphic()) { CodeTreeBuilder builder = method.createBuilder(); int index = 0; - for (NodeExecutionData execution : getModel().getNode().getChildExecutions()) { + for (NodeExecutionData execution : getSpecialization().getNode().getChildExecutions()) { String fieldName = polymorphicTypeName(execution); builder.startStatement(); @@ -227,7 +232,6 @@ CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, FINAL), context.getType(void.class), "adoptChildren0"); method.getParameters().add(new CodeVariableElement(context.getTruffleTypes().getNode(), "other")); method.getParameters().add(new CodeVariableElement(context.getTruffleTypes().getNode(), "newNext")); - NodeData node = getModel().getNode(); CodeTreeBuilder builder = method.createBuilder(); List executions = node.getChildExecutions(); @@ -253,11 +257,11 @@ builder.end(); } - if (getModel().getNode().isPolymorphic(context)) { + if (getSpecialization().getNode().isPolymorphic(context)) { builder.startIf().string("newNext == null").end().startBlock(); builder.statement("this.next0 = null"); builder.end().startElseBlock(); - builder.statement("this.next0 = (" + baseClassName(getModel().getNode()) + ") newNext"); + builder.statement("this.next0 = (" + baseClassName(getSpecialization().getNode()) + ") newNext"); builder.end(); } @@ -265,7 +269,6 @@ } private List createImplicitChildrenAccessors() { - NodeData node = getModel().getNode(); List> prototype = Collections.nCopies(node.getGenericSpecialization().getParameters().size(), null); List> expectTypes = new ArrayList<>(prototype); @@ -317,15 +320,15 @@ private CodeTree truffleBooleanOption(CodeTreeBuilder parent, String name) { CodeTreeBuilder builder = parent.create(); - builder.staticReference(getContext().getTruffleTypes().getTruffleOptions(), name); + builder.staticReference(context.getTruffleTypes().getTruffleOptions(), name); return builder.getRoot(); } - private final void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean disableFrame, boolean evaluated) { - if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) { - method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); + private final void addInternalValueParameters(CodeExecutableElement executableMethod, TemplateMethod method, boolean forceFrame, boolean disableFrame, boolean evaluated) { + if (forceFrame && !disableFrame && method.getSpecification().findParameterSpec("frame") != null) { + executableMethod.addParameter(new CodeVariableElement(context.getTruffleTypes().getFrame(), "frameValue")); } - for (Parameter parameter : specialization.getParameters()) { + for (Parameter parameter : method.getParameters()) { ParameterSpec spec = parameter.getSpecification(); if ((disableFrame || forceFrame) && spec.getName().equals("frame")) { continue; @@ -339,13 +342,13 @@ name = valueNameEvaluated(parameter); } - method.addParameter(new CodeVariableElement(parameter.getType(), name)); + executableMethod.addParameter(new CodeVariableElement(parameter.getType(), name)); } } - private Element createInfoMessage(NodeData node) { - CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), CREATE_INFO); - method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message")); + private Element createInfoMessage() { + CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), context.getType(String.class), CREATE_INFO); + method.addParameter(new CodeVariableElement(context.getType(String.class), "message")); addInternalValueParameters(method, node.getGenericSpecialization(), false, false, false); CodeTreeBuilder builder = method.createBuilder(); @@ -399,23 +402,23 @@ return method; } - private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph) { + private CodeExecutableElement createCachedExecute(SpecializationData polymorph) { CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_CHAINED); addInternalValueParameters(cachedExecute, polymorph, true, false, false); ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0); - boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(getContext()); + boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(context); if (sourceThrowsUnexpected && sourceExecutableType.getType().equals(node.getGenericSpecialization().getReturnType().getTypeSystemType())) { sourceThrowsUnexpected = false; } if (sourceThrowsUnexpected) { - cachedExecute.getThrownTypes().add(getContext().getType(UnexpectedResultException.class)); + cachedExecute.getThrownTypes().add(context.getType(UnexpectedResultException.class)); } return cachedExecute; } - private void createConstructors(NodeData node, CodeTypeElement clazz) { + private void createConstructors(CodeTypeElement clazz) { List constructors = findUserConstructors(node.getNodeType()); ExecutableElement sourceSectionConstructor = null; if (constructors.isEmpty()) { @@ -428,7 +431,7 @@ } } } - if (node.needsRewrites(getContext())) { + if (node.needsRewrites(context)) { ExecutableElement copyConstructor = findCopyConstructor(node.getNodeType()); clazz.add(createCopyConstructor(clazz, copyConstructor, sourceSectionConstructor)); } @@ -438,8 +441,6 @@ CodeExecutableElement method = new CodeExecutableElement(null, type.getSimpleName().toString()); CodeTreeBuilder builder = method.createBuilder(); - NodeData node = getModel().getNode(); - if (superConstructor != null) { for (VariableElement param : superConstructor.getParameters()) { method.getParameters().add(CodeVariableElement.clone(param)); @@ -478,7 +479,7 @@ } private CodeTree createStaticCast(CodeTreeBuilder parent, NodeChildData child, String fieldName) { - NodeData parentNode = getModel().getNode(); + NodeData parentNode = getSpecialization().getNode(); if (child != null) { CreateCastData createCast = parentNode.findCast(child.getName()); if (createCast != null) { @@ -505,7 +506,7 @@ } final String varName = var.getSimpleName().toString(); final TypeMirror varType = var.asType(); - if (ElementUtils.isAssignable(varType, getContext().getTruffleTypes().getNodeArray())) { + if (ElementUtils.isAssignable(varType, context.getTruffleTypes().getNodeArray())) { CodeTree size = builder.create().string("copy.", varName, ".length").getRoot(); builder.startStatement().string("this.").string(varName).string(" = ").startNewArray((ArrayType) varType, size).end().end(); } else { @@ -517,7 +518,7 @@ } private CodeVariableElement createAssumptionField(String assumption) { - CodeVariableElement var = new CodeVariableElement(getContext().getTruffleTypes().getAssumption(), assumption); + CodeVariableElement var = new CodeVariableElement(context.getTruffleTypes().getAssumption(), assumption); var.getModifiers().add(Modifier.FINAL); return var; } @@ -530,9 +531,9 @@ DeclaredType annotationType; if (child.getCardinality() == Cardinality.MANY) { var.getModifiers().add(Modifier.FINAL); - annotationType = getContext().getTruffleTypes().getChildrenAnnotation(); + annotationType = context.getTruffleTypes().getChildrenAnnotation(); } else { - annotationType = getContext().getTruffleTypes().getChildAnnotation(); + annotationType = context.getTruffleTypes().getChildAnnotation(); } var.getAnnotationMirrors().add(new CodeAnnotationMirror(annotationType)); @@ -553,13 +554,12 @@ } protected final CodeExecutableElement createExecuteUninitialized() { - NodeData node = getModel().getNode(); SpecializationData generic = node.getGenericSpecialization(); CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), generic.getReturnType().getType(), EXECUTE_UNINITIALIZED); addInternalValueParameters(method, generic, true, false, false); CodeTreeBuilder builder = method.createBuilder(); - boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); + boolean needsFrame = node.isFrameUsedByAnyGuard(context); CodeTreeBuilder createSpecializationCall = builder.create(); createSpecializationCall.startCall(SPECIALIZE); addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); @@ -602,18 +602,16 @@ } private CodeExecutableElement createMonomorphicRewrite() { - NodeData node = getModel().getNode(); - SpecializationData generic = node.getGenericSpecialization(); CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), generic.getReturnType().getType(), REWRITE); addInternalValueParameters(method, generic, true, false, false); - method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); + method.addParameter(new CodeVariableElement(context.getType(String.class), "reason")); - boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); + boolean needsFrame = node.isFrameUsedByAnyGuard(context); CodeTreeBuilder builder = method.createBuilder(); builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end().end(); - String baseClassName = baseClassName(getModel().getNode()); + String baseClassName = baseClassName(getSpecialization().getNode()); CodeTreeBuilder createSpecializationCall = builder.create(); createSpecializationCall.startCall(SPECIALIZE); addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); @@ -631,13 +629,13 @@ builder.end(); builder.startStatement(); - builder.type(getContext().getType(String.class)).string(" message = ").tree(createInfoCall(builder, generic, "reason")); + builder.type(context.getType(String.class)).string(" message = ").tree(createInfoCall(builder, generic, "reason")); builder.end(); builder.declaration(baseClassName, "returnNode", builder.create().startStaticCall(context.getTruffleTypes().getDslShare(), DSLSHARE_REWRITE).string("this").string("newNode").string("message").end().getRoot()); builder.startIf().string("returnNode == null").end().startBlock(); - builder.tree(createRewritePolymorphic(builder, node, "this")); + builder.tree(createRewritePolymorphic(builder, "this")); builder.end(); builder.startReturn(); @@ -649,7 +647,7 @@ return method; } - private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) { + private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, String currentNode) { String polyClassName = nodePolymorphicClassName(node); CodeTreeBuilder builder = parent.create(); @@ -667,14 +665,14 @@ return builder.getRoot(); } - private CodeExecutableElement createCreateSpecializationMethod(NodeData node, SpecializationGroup group) { + private CodeExecutableElement createCreateSpecializationMethod(SpecializationGroup group) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), new GeneratedTypeMirror(ElementUtils.getPackageName(node.getTemplateType()), baseClassName(node)), SPECIALIZE); - final boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); + final boolean needsFrame = node.isFrameUsedByAnyGuard(context); if (!needsFrame) { - method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getTruffleBoundary())); + method.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getTruffleTypes().getTruffleBoundary())); } addInternalValueParameters(method, node.getGenericSpecialization(), needsFrame, !needsFrame, false); @@ -707,7 +705,7 @@ builder.tree(createDeoptimize(builder)); } builder.startReturn(); - builder.cast(baseClassName(getModel().getNode())); + builder.cast(baseClassName(getSpecialization().getNode())); builder.startGroup().startCall(className, NodeFactoryFactory.FACTORY_METHOD_NAME).string("this"); for (Parameter param : current.getSignatureParameters()) { NodeChildData child = param.getSpecification().getExecution().getChild(); @@ -802,8 +800,6 @@ } private int emitGuards(CodeTreeBuilder builder, SpecializationData source, SpecializationGroup group, boolean emitAssumptions, boolean typedCasts, boolean castForGuardsOnly) { - NodeData node = source.getNode(); - CodeTreeBuilder guardsBuilder = builder.create(); CodeTreeBuilder castBuilder = builder.create(); CodeTreeBuilder guardsCastBuilder = builder.create(); @@ -935,7 +931,7 @@ } private CodeTree createTypeGuard(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) { - NodeData node = execution.getChild().getNodeData(); + NodeData childNode = execution.getChild().getNodeData(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); @@ -957,7 +953,7 @@ String castMethodName; String castTypeName = null; - List types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + List types = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType); if (types.size() > 1) { castMethodName = TypeSystemCodeGenerator.isImplicitTypeMethodName(targetType); if (typedCasts) { @@ -967,7 +963,7 @@ castMethodName = TypeSystemCodeGenerator.isTypeMethodName(targetType); } - startCallTypeSystemMethod(builder, node.getTypeSystem(), castMethodName); + startCallTypeSystemMethod(builder, childNode.getTypeSystem(), castMethodName); builder.string(valueName(source)); if (castTypeName != null) { builder.string(castTypeName); @@ -985,7 +981,7 @@ // TODO merge redundancies with #createTypeGuard private CodeTree createCast(CodeTreeBuilder parent, NodeExecutionData execution, Parameter source, TypeData targetType, boolean typedCasts) { - NodeData node = execution.getChild().getNodeData(); + NodeData childNode = execution.getChild().getNodeData(); TypeData sourceType = source.getTypeSystemType(); if (!sourceType.needsCastTo(targetType)) { @@ -1001,7 +997,7 @@ String castMethodName; String castTypeName = null; - List types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + List types = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType); if (types.size() > 1) { castMethodName = TypeSystemCodeGenerator.asImplicitTypeMethodName(targetType); if (typedCasts) { @@ -1017,7 +1013,7 @@ args.add(CodeTreeBuilder.singleString(castTypeName)); } - CodeTree cast = createCallTypeSystemMethod(parent, node, castMethodName, args.toArray(new CodeTree[0])); + CodeTree cast = createCallTypeSystemMethod(parent, childNode, castMethodName, args.toArray(new CodeTree[0])); CodeTreeBuilder builder = parent.create(); builder.tree(createLazyAssignment(parent, castValueName(source), targetType.getPrimitiveType(), condition, cast)); @@ -1034,11 +1030,11 @@ } CodeTreeBuilder builder = parent.create(); - List types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + List types = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType); if (types.size() > 1) { CodeTree castType = createCallTypeSystemMethod(parent, execution.getChild().getNodeData(), TypeSystemCodeGenerator.getImplicitClass(targetType), CodeTreeBuilder.singleString(valueName(source))); - builder.tree(createLazyAssignment(builder, implicitTypeName(source), getContext().getType(Class.class), condition, castType)); + builder.tree(createLazyAssignment(builder, implicitTypeName(source), context.getType(Class.class), condition, castType)); } return builder.getRoot(); } @@ -1057,7 +1053,7 @@ CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (current.getMethod() == null) { - emitEncounteredSynthetic(builder, getModel().getNode(), current); + emitEncounteredSynthetic(builder, getSpecialization().getNode(), current); } else { builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end(); } @@ -1076,7 +1072,7 @@ for (SpecializationThrowsData exception : current.getExceptions()) { builder.end().startCatchBlock(exception.getJavaClass(), "rewriteEx"); builder.tree(createDeoptimize(builder)); - builder.tree(createCallRewriteMonomorphic(builder, false, current.getNode().getGenericSpecialization().getReturnType().getTypeSystemType(), current, null, + builder.tree(createCallRewriteMonomorphic(builder, false, current.getNode().getGenericSpecialization().getReturnType().getTypeSystemType(), null, "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass()))); } builder.end(); @@ -1084,14 +1080,13 @@ return builder.getRoot(); } - protected CodeTree createCastingExecute(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData executable, ExecutableTypeData castExecutable) { + protected CodeTree createCastingExecute(CodeTreeBuilder parent, ExecutableTypeData executable, ExecutableTypeData castExecutable) { TypeData type = executable.getType(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); - NodeData node = specialization.getNode(); TypeData primaryType = castExecutable.getType(); - boolean needsTry = castExecutable.hasUnexpectedValue(getContext()); + boolean needsTry = castExecutable.hasUnexpectedValue(context); boolean returnVoid = type.isVoid(); List executeParameters = new ArrayList<>(); @@ -1109,7 +1104,7 @@ } builder.tree(createExecuteChildren(builder, executable, specialization, executeParameters, null)); - boolean hasUnexpected = executable.hasUnexpectedValue(getContext()); + boolean hasUnexpected = executable.hasUnexpectedValue(context); CodeTree primaryExecuteCall = createTemplateMethodCall(builder, null, executable, castExecutable, null, executeParameterNames); if (needsTry) { @@ -1160,7 +1155,7 @@ return createCastType(node.getTypeSystem(), sourceType, exepctedType, hasUnexpected, value); } - protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData specialization, List targetParameters, + protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData currentSpecialization, List targetParameters, Parameter unexpectedParameter) { CodeTreeBuilder builder = parent.create(); for (Parameter targetParameter : targetParameters) { @@ -1169,8 +1164,9 @@ } NodeExecutionData execution = targetParameter.getSpecification().getExecution(); CodeTree executionExpressions = createExecuteChild(builder, execution, sourceExecutable, targetParameter, unexpectedParameter); - CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, specialization, sourceExecutable, targetParameter, execution.isShortCircuit(), unexpectedParameter); - CodeTree shortCircuitTree = createShortCircuitTree(builder, unexpectedTree, specialization, targetParameter, unexpectedParameter); + CodeTree unexpectedTree = createCatchUnexpectedTree(builder, executionExpressions, currentSpecialization, sourceExecutable, targetParameter, execution.isShortCircuit(), + unexpectedParameter); + CodeTree shortCircuitTree = createShortCircuitTree(builder, unexpectedTree, currentSpecialization, targetParameter, unexpectedParameter); if (shortCircuitTree == executionExpressions) { if (containsNewLine(executionExpressions)) { @@ -1188,15 +1184,14 @@ } private ExecutableTypeData resolveExecutableType(NodeExecutionData execution, TypeData type) { - ExecutableTypeData targetExecutable = execution.getChild().findExecutableType(getContext(), type); + ExecutableTypeData targetExecutable = execution.getChild().findExecutableType(context, type); if (targetExecutable == null) { - targetExecutable = execution.getChild().findAnyGenericExecutableType(getContext()); + targetExecutable = execution.getChild().findAnyGenericExecutableType(context); } return targetExecutable; } private CodeTree createExecuteChild(CodeTreeBuilder parent, NodeExecutionData execution, ExecutableTypeData sourceExecutable, Parameter targetParameter, Parameter unexpectedParameter) { - SpecializationData specialization = getModel(); if (specialization.isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { List possiblePolymorphicTypes = lookupPolymorphicTargetTypes(targetParameter); if (possiblePolymorphicTypes.size() > 1) { @@ -1242,7 +1237,6 @@ } private final List lookupPolymorphicTargetTypes(Parameter param) { - SpecializationData specialization = getModel(); Set possiblePolymorphicTypes = new HashSet<>(); for (SpecializationData otherSpecialization : specialization.getNode().getSpecializations()) { if (!otherSpecialization.isSpecialized()) { @@ -1332,12 +1326,12 @@ } CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, expectType != null ? STATIC : FINAL), param.getType(), childExecuteName); - method.getThrownTypes().add(getContext().getTruffleTypes().getUnexpectedValueException()); - method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); + method.getThrownTypes().add(context.getTruffleTypes().getUnexpectedValueException()); + method.addParameter(new CodeVariableElement(context.getTruffleTypes().getFrame(), "frameValue")); if (expectType != null) { method.addParameter(new CodeVariableElement(expectType.getPrimitiveType(), valueNameEvaluated(param))); } - method.addParameter(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(param))); + method.addParameter(new CodeVariableElement(context.getType(Class.class), implicitTypeName(param))); CodeTreeBuilder builder = method.createBuilder(); builder.declaration(param.getType(), valueName(param)); @@ -1349,7 +1343,6 @@ private CodeTree createExecuteChildImplicitExpressions(CodeTreeBuilder parent, Parameter targetParameter, TypeData expectType) { CodeTreeBuilder builder = parent.create(); - NodeData node = getModel().getNode(); NodeExecutionData execution = targetParameter.getSpecification().getExecution(); List sourceTypes = node.getTypeSystem().lookupSourceTypes(targetParameter.getTypeSystemType()); boolean elseIf = false; @@ -1364,7 +1357,7 @@ builder.startElseBlock(); } - ExecutableTypeData implictExecutableTypeData = execution.getChild().findExecutableType(getContext(), sourceType); + ExecutableTypeData implictExecutableTypeData = execution.getChild().findExecutableType(context, sourceType); if (implictExecutableTypeData == null) { /* * For children with executeWith.size() > 0 an executable type may not exist so use @@ -1448,7 +1441,7 @@ private boolean hasUnexpected(Parameter sourceParameter, Parameter targetParameter, Parameter unexpectedParameter) { NodeExecutionData execution = targetParameter.getSpecification().getExecution(); - if (getModel().isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { + if (getSpecialization().isPolymorphic() && targetParameter.getTypeSystemType().isGeneric() && unexpectedParameter == null) { // check for other polymorphic types List polymorphicTargetTypes = lookupPolymorphicTargetTypes(targetParameter); if (polymorphicTargetTypes.size() > 1) { @@ -1467,7 +1460,7 @@ } private boolean hasUnexpectedType(NodeExecutionData execution, Parameter sourceParameter, TypeData targetType) { - List implicitSourceTypes = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + List implicitSourceTypes = getSpecialization().getNode().getTypeSystem().lookupSourceTypes(targetType); for (TypeData implicitSourceType : implicitSourceTypes) { TypeData sourceType; @@ -1475,13 +1468,13 @@ if (sourceParameter != null) { sourceType = sourceParameter.getTypeSystemType(); } else { - if (targetExecutable.hasUnexpectedValue(getContext())) { + if (targetExecutable.hasUnexpectedValue(context)) { return true; } sourceType = targetExecutable.getType(); } - ImplicitCastData cast = getModel().getNode().getTypeSystem().lookupCast(implicitSourceType, targetType); + ImplicitCastData cast = getSpecialization().getNode().getTypeSystem().lookupCast(implicitSourceType, targetType); if (cast != null) { if (cast.getSourceType().needsCastTo(targetType)) { return true; @@ -1495,8 +1488,8 @@ return false; } - private CodeTree createCatchUnexpectedTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, ExecutableTypeData currentExecutable, Parameter param, boolean shortCircuit, - Parameter unexpectedParameter) { + private CodeTree createCatchUnexpectedTree(CodeTreeBuilder parent, CodeTree body, SpecializationData currentSpecialization, ExecutableTypeData currentExecutable, Parameter param, + boolean shortCircuit, Parameter unexpectedParameter) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); Parameter sourceParameter = currentExecutable.findParameter(param.getLocalName()); boolean unexpected = hasUnexpected(sourceParameter, param, unexpectedParameter); @@ -1516,34 +1509,33 @@ } builder.end().startCatchBlock(getUnexpectedValueException(), "ex"); - SpecializationData generic = specialization.getNode().getGenericSpecialization(); + SpecializationData generic = currentSpecialization.getNode().getGenericSpecialization(); Parameter genericParameter = generic.findParameter(param.getLocalName()); List genericParameters = generic.getParametersAfter(genericParameter); builder.tree(createExecuteChildren(parent, currentExecutable, generic, genericParameters, genericParameter)); - if (specialization.isPolymorphic()) { - builder.tree(createReturnOptimizeTypes(builder, currentExecutable, specialization, param)); + if (currentSpecialization.isPolymorphic()) { + builder.tree(createReturnOptimizeTypes(builder, currentExecutable, currentSpecialization, param)); } else { - builder.tree(createCallRewriteMonomorphic(builder, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), specialization, param, "Expected " + param.getLocalName() + - " instanceof " + ElementUtils.getSimpleName(param.getType()))); + builder.tree(createCallRewriteMonomorphic(builder, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), param, "Expected " + param.getLocalName() + " instanceof " + + ElementUtils.getSimpleName(param.getType()))); } builder.end(); // catch block return builder.getRoot(); } - private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, ExecutableTypeData currentExecutable, SpecializationData specialization, Parameter param) { - NodeData node = specialization.getNode(); + private CodeTree createReturnOptimizeTypes(CodeTreeBuilder parent, ExecutableTypeData currentExecutable, SpecializationData currentSpecialization, Parameter param) { SpecializationData polymorphic = node.getPolymorphicSpecialization(); CodeTreeBuilder builder = new CodeTreeBuilder(parent); - builder.startStatement().string(polymorphicTypeName(param.getSpecification().getExecution())).string(" = ").typeLiteral(getContext().getType(Object.class)).end(); + builder.startStatement().string(polymorphicTypeName(param.getSpecification().getExecution())).string(" = ").typeLiteral(context.getType(Object.class)).end(); builder.startReturn(); CodeTreeBuilder execute = new CodeTreeBuilder(builder); execute.startCall("next0", EXECUTE_CHAINED); - addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, false, null); + addInternalValueParameterNames(execute, currentSpecialization, polymorphic, param.getLocalName(), true, false, null); execute.end(); TypeData sourceType = polymorphic.getReturnType().getTypeSystemType(); @@ -1574,8 +1566,8 @@ if (index < targetExecution.getChild().getExecuteWith().size()) { NodeChildData child = targetExecution.getChild().getExecuteWith().get(index); - ParameterSpec spec = getModel().getSpecification().findParameterSpec(child.getName()); - List specializationParams = getModel().findParameters(spec); + ParameterSpec spec = getSpecialization().getSpecification().findParameterSpec(child.getName()); + List specializationParams = getSpecialization().findParameters(spec); if (specializationParams.isEmpty()) { builder.defaultValue(parameter.getType()); @@ -1590,13 +1582,13 @@ if (unexpectedParameter != null && unexpectedParameter.getLocalName().equals(specializationParam.getLocalName())) { localName = "ex.getResult()"; - sourceType = getModel().getNode().getTypeSystem().getGenericTypeData(); + sourceType = getSpecialization().getNode().getTypeSystem().getGenericTypeData(); } CodeTree value = CodeTreeBuilder.singleString(localName); if (sourceType.needsCastTo(targetType)) { - value = createCallTypeSystemMethod(builder, getModel().getNode(), TypeSystemCodeGenerator.asTypeMethodName(targetType), value); + value = createCallTypeSystemMethod(builder, getSpecialization().getNode(), TypeSystemCodeGenerator.asTypeMethodName(targetType), value); } builder.tree(value); } else { @@ -1611,15 +1603,15 @@ return builder.getRoot(); } - private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData specialization, Parameter parameter, Parameter exceptionParam) { + private CodeTree createShortCircuitTree(CodeTreeBuilder parent, CodeTree body, SpecializationData currentSpecialization, Parameter parameter, Parameter exceptionParam) { NodeExecutionData execution = parameter.getSpecification().getExecution(); if (execution == null || !execution.isShortCircuit()) { return body; } CodeTreeBuilder builder = new CodeTreeBuilder(parent); - Parameter shortCircuitParam = specialization.getPreviousParam(parameter); - builder.tree(createShortCircuitValue(builder, specialization, execution, shortCircuitParam, exceptionParam)); + Parameter shortCircuitParam = currentSpecialization.getPreviousParam(parameter); + builder.tree(createShortCircuitValue(builder, currentSpecialization, execution, shortCircuitParam, exceptionParam)); builder.declaration(parameter.getType(), valueName(parameter), CodeTreeBuilder.createBuilder().defaultValue(parameter.getType())); builder.startIf().string(shortCircuitParam.getLocalName()).end(); builder.startBlock(); @@ -1654,8 +1646,7 @@ return builder.getRoot(); } - protected CodeTree createCallRewriteMonomorphic(CodeTreeBuilder parent, boolean hasUnexpected, TypeData returnType, SpecializationData current, Parameter exceptionParam, String reason) { - NodeData node = current.getNode(); + protected CodeTree createCallRewriteMonomorphic(CodeTreeBuilder parent, boolean hasUnexpected, TypeData returnType, Parameter exceptionParam, String reason) { SpecializationData generic = node.getGenericSpecialization(); CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); specializeCall.startCall(REWRITE); @@ -2014,7 +2005,7 @@ } private TypeMirror getUnexpectedValueException() { - return getContext().getTruffleTypes().getUnexpectedValueException(); + return context.getTruffleTypes().getUnexpectedValueException(); } interface CodeBlock { diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java Mon Dec 29 23:38:16 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java Mon Dec 29 23:38:21 2014 +0100 @@ -26,27 +26,69 @@ import javax.lang.model.element.*; +import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.model.*; -public class NodeCodeGenerator extends AbstractCompilationUnitFactory { +public class NodeCodeGenerator extends CodeTypeElementFactory { @Override - @SuppressWarnings("unchecked") - protected void createChildren(NodeData node) { - List casts = new ArrayList<>(getElement().getEnclosedElements()); - getElement().getEnclosedElements().clear(); + public CodeTypeElement create(ProcessorContext context, NodeData node) { + List enclosedTypes = new ArrayList<>(); + for (NodeData childNode : node.getEnclosingNodes()) { + CodeTypeElement type = create(context, childNode); + if (type != null) { + enclosedTypes.add(type); + } + } + List generatedNodes = generateNodes(context, node); - Map> childTypes = new LinkedHashMap<>(); - for (NodeData nodeChild : node.getEnclosingNodes()) { - NodeCodeGenerator generator = new NodeCodeGenerator(); - childTypes.put(nodeChild, generator.process(null, nodeChild).getEnclosedElements()); - } + if (!generatedNodes.isEmpty() || !enclosedTypes.isEmpty()) { + CodeTypeElement type = wrapGeneratedNodes(context, node, generatedNodes); - if (node.needsFactory() || node.getNodeDeclaringChildren().size() > 0) { - NodeFactoryFactory factory = new NodeFactoryFactory(childTypes); - add(factory, node); - factory.getElement().getEnclosedElements().addAll(casts); + for (CodeTypeElement enclosedFactory : enclosedTypes) { + Set modifiers = enclosedFactory.getModifiers(); + if (!modifiers.contains(Modifier.STATIC)) { + modifiers.add(Modifier.STATIC); + } + type.add(enclosedFactory); + } + return type; + } else { + return null; } } + + private static CodeTypeElement wrapGeneratedNodes(ProcessorContext context, NodeData node, List generatedNodes) { + // wrap all types into a generated factory + CodeTypeElement factoryElement = new NodeFactoryFactory(context, node, generatedNodes.isEmpty() ? null : generatedNodes.get(0)).create(); + for (CodeTypeElement generatedNode : generatedNodes) { + factoryElement.add(generatedNode); + } + return factoryElement; + } + + private static List generateNodes(ProcessorContext context, NodeData node) { + if (!node.needsFactory()) { + return Collections.emptyList(); + } + List nodeTypes = new ArrayList<>(); + SpecializationData generic = node.getGenericSpecialization() == null ? node.getSpecializations().get(0) : node.getGenericSpecialization(); + CodeTypeElement baseNode = new NodeBaseFactory(context, node, generic).create(); + nodeTypes.add(baseNode); + + for (SpecializationData specialization : node.getSpecializations()) { + if (!specialization.isReachable() || specialization.isGeneric()) { + continue; + } + if (specialization.isPolymorphic() && node.isPolymorphic(context)) { + nodeTypes.add(new PolymorphicNodeFactory(context, node, specialization, baseNode).create()); + continue; + } + + nodeTypes.add(new SpecializedNodeFactory(context, node, specialization, baseNode).create()); + } + return nodeTypes; + } + } diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeFactoryFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeFactoryFactory.java Mon Dec 29 23:38:16 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeFactoryFactory.java Mon Dec 29 23:38:21 2014 +0100 @@ -32,100 +32,59 @@ import javax.lang.model.util.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror; import com.oracle.truffle.dsl.processor.model.*; -class NodeFactoryFactory extends AbstractClassElementFactory { +class NodeFactoryFactory { static final String FACTORY_METHOD_NAME = "create0"; - private final Map> childTypes; - private CodeTypeElement generatedNode; + private final ProcessorContext context; + private final NodeData node; + private final CodeTypeElement createdFactoryElement; - NodeFactoryFactory(Map> childElements) { - this.childTypes = childElements; + public NodeFactoryFactory(ProcessorContext context, NodeData node, CodeTypeElement createdClass) { + this.context = context; + this.node = node; + this.createdFactoryElement = createdClass; } private static String factoryClassName(NodeData node) { return node.getNodeId() + "Factory"; } - @Override - protected CodeTypeElement create(NodeData node) { + public CodeTypeElement create() { Modifier visibility = ElementUtils.getVisibility(node.getTemplateType().getModifiers()); + TypeMirror nodeFactory = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(context.getTruffleTypes().getNodeFactoryBase()), node.getNodeType()); - CodeTypeElement clazz = createClass(node, modifiers(), factoryClassName(node), null, false); + CodeTypeElement clazz = GeneratorUtils.createClass(node, modifiers(), factoryClassName(node), null, false); if (visibility != null) { clazz.getModifiers().add(visibility); } clazz.getModifiers().add(Modifier.FINAL); - return clazz; - } - @Override - protected void createChildren(NodeData node) { - CodeTypeElement clazz = getElement(); - - Modifier createVisibility = ElementUtils.getVisibility(clazz.getModifiers()); - - if (node.needsFactory()) { - NodeBaseFactory factory = new NodeBaseFactory(); - add(factory, node.getGenericSpecialization() == null ? node.getSpecializations().get(0) : node.getGenericSpecialization()); - generatedNode = factory.getElement(); - - createFactoryMethods(node, clazz, createVisibility); - - for (SpecializationData specialization : node.getSpecializations()) { - if (!specialization.isReachable() || specialization.isGeneric()) { - continue; - } - - if (specialization.isPolymorphic() && node.isPolymorphic(context)) { - PolymorphicNodeFactory polymorphicFactory = new PolymorphicNodeFactory(generatedNode); - add(polymorphicFactory, specialization); - continue; - } + if (createdFactoryElement != null) { + createFactoryMethods(clazz, visibility); - add(new SpecializedNodeFactory(generatedNode), specialization); - } - - TypeMirror nodeFactory = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(getContext().getTruffleTypes().getNodeFactoryBase()), node.getNodeType()); clazz.setSuperClass(nodeFactory); - clazz.add(createNodeFactoryConstructor(node)); - clazz.add(createCreateNodeMethod(node)); - clazz.add(createGetInstanceMethod(node, createVisibility)); - clazz.add(createInstanceConstant(node, clazz.asType())); - } - - for (NodeData childNode : childTypes.keySet()) { - if (childNode.getTemplateType().getModifiers().contains(Modifier.PRIVATE)) { - continue; - } - - for (TypeElement type : childTypes.get(childNode)) { - Set typeModifiers = ((CodeTypeElement) type).getModifiers(); - Modifier visibility = ElementUtils.getVisibility(type.getModifiers()); - typeModifiers.clear(); - if (visibility != null) { - typeModifiers.add(visibility); - } - - typeModifiers.add(Modifier.STATIC); - typeModifiers.add(Modifier.FINAL); - clazz.add(type); - } + clazz.add(createNodeFactoryConstructor()); + clazz.add(createCreateNodeMethod()); + clazz.add(createGetInstanceMethod(visibility)); + clazz.add(createInstanceConstant(clazz.asType())); } List children = node.getNodeDeclaringChildren(); if (node.getDeclaringNode() == null && children.size() > 0) { - clazz.add(createGetFactories(node)); + clazz.add(createGetFactories()); } + return clazz; } - private Element createNodeFactoryConstructor(NodeData node) { + private Element createNodeFactoryConstructor() { CodeExecutableElement method = new CodeExecutableElement(modifiers(PRIVATE), null, factoryClassName(node)); CodeTreeBuilder builder = method.createBuilder(); builder.startStatement(); @@ -150,7 +109,7 @@ // node signatures builder.startGroup(); builder.startNewArray(new ArrayCodeTypeMirror(new ArrayCodeTypeMirror(context.getType(Class.class))), null); - List constructors = NodeBaseFactory.findUserConstructors(generatedNode.asType()); + List constructors = NodeBaseFactory.findUserConstructors(createdFactoryElement.asType()); for (ExecutableElement constructor : constructors) { builder.startGroup(); if (constructor.getParameters().isEmpty()) { @@ -171,14 +130,14 @@ return method; } - private CodeExecutableElement createCreateNodeMethod(NodeData node) { + private CodeExecutableElement createCreateNodeMethod() { CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), node.getNodeType(), "createNode"); - CodeVariableElement arguments = new CodeVariableElement(getContext().getType(Object.class), "arguments"); + CodeVariableElement arguments = new CodeVariableElement(context.getType(Object.class), "arguments"); method.setVarArgs(true); method.addParameter(arguments); CodeTreeBuilder builder = method.createBuilder(); - List signatures = NodeBaseFactory.findUserConstructors(generatedNode.asType()); + List signatures = NodeBaseFactory.findUserConstructors(createdFactoryElement.asType()); boolean ifStarted = false; for (ExecutableElement element : signatures) { @@ -195,7 +154,7 @@ builder.string("(arguments[" + index + "] == null || "); } builder.string("arguments[" + index + "] instanceof "); - builder.type(ElementUtils.boxType(getContext(), param.asType())); + builder.type(ElementUtils.boxType(context, param.asType())); if (!param.asType().getKind().isPrimitive()) { builder.string(")"); } @@ -221,15 +180,15 @@ } builder.startElseBlock(); - builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)); + builder.startThrow().startNew(context.getType(IllegalArgumentException.class)); builder.doubleQuote("Invalid create signature."); builder.end().end(); builder.end(); // else block return method; } - private ExecutableElement createGetInstanceMethod(NodeData node, Modifier visibility) { - TypeElement nodeFactoryType = ElementUtils.fromTypeMirror(getContext().getType(NodeFactory.class)); + private ExecutableElement createGetInstanceMethod(Modifier visibility) { + TypeElement nodeFactoryType = ElementUtils.fromTypeMirror(context.getType(NodeFactory.class)); TypeMirror returnType = ElementUtils.getDeclaredType(nodeFactoryType, node.getNodeType()); CodeExecutableElement method = new CodeExecutableElement(modifiers(), returnType, "getInstance"); @@ -264,7 +223,7 @@ } } - private static CodeVariableElement createInstanceConstant(NodeData node, TypeMirror factoryType) { + private CodeVariableElement createInstanceConstant(TypeMirror factoryType) { String varName = instanceVarName(node); CodeVariableElement var = new CodeVariableElement(modifiers(), factoryType, varName); var.getModifiers().add(Modifier.PRIVATE); @@ -272,7 +231,7 @@ return var; } - private ExecutableElement createGetFactories(NodeData node) { + private ExecutableElement createGetFactories() { List children = node.getNodeDeclaringChildren(); if (node.needsFactory()) { children.add(node); @@ -288,23 +247,23 @@ } prev = child.getNodeType(); } - TypeMirror commonNodeSuperType = ElementUtils.getCommonSuperType(getContext(), nodeTypesList.toArray(new TypeMirror[nodeTypesList.size()])); + TypeMirror commonNodeSuperType = ElementUtils.getCommonSuperType(context, nodeTypesList.toArray(new TypeMirror[nodeTypesList.size()])); - Types types = getContext().getEnvironment().getTypeUtils(); - TypeMirror factoryType = getContext().getType(NodeFactory.class); + Types types = context.getEnvironment().getTypeUtils(); + TypeMirror factoryType = context.getType(NodeFactory.class); TypeMirror baseType; if (allSame) { baseType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(factoryType), commonNodeSuperType); } else { baseType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(factoryType), types.getWildcardType(commonNodeSuperType, null)); } - TypeMirror listType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(getContext().getType(List.class)), baseType); + TypeMirror listType = ElementUtils.getDeclaredType(ElementUtils.fromTypeMirror(context.getType(List.class)), baseType); CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC, STATIC), listType, "getFactories"); CodeTreeBuilder builder = method.createBuilder(); builder.startReturn(); - builder.startStaticCall(getContext().getType(Arrays.class), "asList"); + builder.startStaticCall(context.getType(Arrays.class), "asList"); for (NodeData child : children) { builder.startGroup(); @@ -326,15 +285,15 @@ return method; } - private void createFactoryMethods(NodeData node, CodeTypeElement clazz, Modifier createVisibility) { - List constructors = NodeBaseFactory.findUserConstructors(generatedNode.asType()); + private void createFactoryMethods(CodeTypeElement clazz, Modifier createVisibility) { + List constructors = NodeBaseFactory.findUserConstructors(createdFactoryElement.asType()); for (ExecutableElement constructor : constructors) { - clazz.add(createCreateMethod(node, createVisibility, constructor)); + clazz.add(createCreateMethod(createVisibility, constructor)); } } - private CodeExecutableElement createCreateMethod(NodeData node, Modifier visibility, ExecutableElement constructor) { - CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), constructor); + private CodeExecutableElement createCreateMethod(Modifier visibility, ExecutableElement constructor) { + CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), constructor); method.setSimpleName(CodeNames.of("create")); method.getModifiers().clear(); if (visibility != null) { diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/PolymorphicNodeFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/PolymorphicNodeFactory.java Mon Dec 29 23:38:16 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/PolymorphicNodeFactory.java Mon Dec 29 23:38:21 2014 +0100 @@ -30,61 +30,56 @@ import javax.lang.model.type.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.model.*; class PolymorphicNodeFactory extends SpecializedNodeFactory { - public PolymorphicNodeFactory(CodeTypeElement nodeGen) { - super(nodeGen); + public PolymorphicNodeFactory(ProcessorContext context, NodeData node, SpecializationData specialization, CodeTypeElement nodeGen) { + super(context, node, specialization, nodeGen); } @Override - public CodeTypeElement create(SpecializationData polymorph) { - NodeData node = polymorph.getNode(); + public CodeTypeElement create() { TypeMirror baseType = node.getNodeType(); if (nodeGen != null) { baseType = nodeGen.asType(); } - CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false); + CodeTypeElement clazz = GeneratorUtils.createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false); - clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.POLYMORPHIC)); + clazz.getAnnotationMirrors().add(createNodeInfo(NodeCost.POLYMORPHIC)); - for (Parameter polymorphParameter : polymorph.getSignatureParameters()) { + for (Parameter polymorphParameter : specialization.getSignatureParameters()) { if (!polymorphParameter.getTypeSystemType().isGeneric()) { continue; } Set types = new HashSet<>(); - for (SpecializationData specialization : node.getSpecializations()) { - if (!specialization.isSpecialized()) { + for (SpecializationData otherSpecialization : node.getSpecializations()) { + if (!otherSpecialization.isSpecialized()) { continue; } - Parameter parameter = specialization.findParameter(polymorphParameter.getLocalName()); + Parameter parameter = otherSpecialization.findParameter(polymorphParameter.getLocalName()); assert parameter != null; types.add(parameter.getTypeSystemType()); } } - for (NodeExecutionData execution : getModel().getNode().getChildExecutions()) { + for (NodeExecutionData execution : node.getChildExecutions()) { String fieldName = polymorphicTypeName(execution); - CodeVariableElement var = new CodeVariableElement(modifiers(PRIVATE), getContext().getType(Class.class), fieldName); - var.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getCompilationFinal())); + CodeVariableElement var = new CodeVariableElement(modifiers(PRIVATE), context.getType(Class.class), fieldName); + var.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getTruffleTypes().getCompilationFinal())); clazz.add(var); } + createConstructors(clazz); + createExecuteMethods(clazz); + + clazz.add(createUpdateTypes0()); + createCachedExecuteMethods(clazz); + return clazz; } - @Override - protected void createChildren(SpecializationData specialization) { - CodeTypeElement clazz = getElement(); - - createConstructors(clazz); - createExecuteMethods(specialization); - - clazz.add(createUpdateTypes0()); - createCachedExecuteMethods(specialization); - } - } \ No newline at end of file diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java Mon Dec 29 23:38:16 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/SpecializedNodeFactory.java Mon Dec 29 23:38:21 2014 +0100 @@ -32,6 +32,7 @@ import javax.lang.model.util.*; import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror; @@ -42,18 +43,18 @@ protected final CodeTypeElement nodeGen; - public SpecializedNodeFactory(CodeTypeElement nodeGen) { + public SpecializedNodeFactory(ProcessorContext context, NodeData node, SpecializationData specialization, CodeTypeElement nodeGen) { + super(context, node, specialization); this.nodeGen = nodeGen; } @Override - public CodeTypeElement create(SpecializationData specialization) { - NodeData node = specialization.getNode(); + public CodeTypeElement create() { TypeMirror baseType = node.getNodeType(); if (nodeGen != null) { baseType = nodeGen.asType(); } - CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false); + CodeTypeElement clazz = GeneratorUtils.createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false); if (specialization.isSpecialized() || specialization.isUninitialized()) { clazz.add(createGetMetadata0(false)); @@ -72,12 +73,38 @@ } else { throw new AssertionError(); } - clazz.getAnnotationMirrors().add(createNodeInfo(node, cost)); + clazz.getAnnotationMirrors().add(createNodeInfo(cost)); if (specialization.isUninitialized() && node.getGenericSpecialization().isReachable()) { clazz.add(createUninitializedGetCostOverride()); } + createConstructors(clazz); + + createExecuteMethods(clazz); + createCachedExecuteMethods(clazz); + + if (specialization.isUninitialized()) { + if (specialization.getNode().isFallbackReachable()) { + CodeVariableElement var = new CodeVariableElement(modifiers(Modifier.PRIVATE), context.getType(boolean.class), CONTAINS_FALLBACK); + var.addAnnotationMirror(new CodeAnnotationMirror(context.getTruffleTypes().getCompilationFinal())); + clazz.add(var); + } + clazz.add(createExecuteUninitialized()); + } + + if (!specialization.isUninitialized() && specialization.getNode().needsRewrites(context)) { + clazz.add(createCopyConstructorFactoryMethod(clazz, nodeGen.asType())); + } else { + for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) { + if (constructor.getParameters().size() == 1 && ((CodeVariableElement) constructor.getParameters().get(0)).getType().equals(nodeGen.asType())) { + // skip copy constructor - not used + continue; + } + clazz.add(createConstructorFactoryMethod(clazz, constructor)); + } + } + return clazz; } @@ -97,9 +124,6 @@ CodeTreeBuilder builder = includes.createInitBuilder(); - SpecializationData specialization = getModel(); - NodeData node = specialization.getNode(); - Set contains = specialization.getContains(); if (specialization.isUninitialized()) { contains = new HashSet<>(); @@ -115,10 +139,10 @@ } builder.startNew(context.getTruffleTypes().getDslMetadata()); - builder.startGroup().string(nodeSpecializationClassName(getModel()), ".class").end(); + builder.startGroup().string(nodeSpecializationClassName(getSpecialization()), ".class").end(); builder.tree(createSpecializationListLiteral(builder, contains)); - builder.tree(createSpecializationListLiteral(builder, getModel().getExcludedBy())); - builder.tree(createSpecializationTypeLiteral(builder, SpecializationData.getSignatureTypes(getModel()))); + builder.tree(createSpecializationListLiteral(builder, getSpecialization().getExcludedBy())); + builder.tree(createSpecializationTypeLiteral(builder, SpecializationData.getSignatureTypes(getSpecialization()))); builder.string("0").string("0"); builder.end(); return includes; @@ -149,10 +173,10 @@ builder.staticReference(context.getTruffleTypes().getDslMetadata(), EMPTY_CLASS_ARRAY); } else { builder.startNewArray(classArray, null); - for (SpecializationData specialization : list) { - SpecializationData s = specialization; + for (SpecializationData current : list) { + SpecializationData s = current; if (s.isGeneric() || s.isPolymorphic()) { - s = getModel().getNode().getUninitializedSpecialization(); + s = getSpecialization().getNode().getUninitializedSpecialization(); } builder.startGroup().string(nodeSpecializationClassName(s)).string(".class").end(); } @@ -162,54 +186,22 @@ return builder.getRoot(); } - protected CodeAnnotationMirror createNodeInfo(NodeData node, NodeCost cost) { + protected CodeAnnotationMirror createNodeInfo(NodeCost cost) { String shortName = node.getShortName(); - CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(getContext().getTruffleTypes().getNodeInfoAnnotation()); + CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(context.getTruffleTypes().getNodeInfoAnnotation()); if (shortName != null) { nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName)); } - DeclaredType nodeinfoCost = getContext().getTruffleTypes().getNodeCost(); + DeclaredType nodeinfoCost = context.getTruffleTypes().getNodeCost(); VariableElement varKind = ElementUtils.findVariableElement(nodeinfoCost, cost.name()); nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("cost"), new CodeAnnotationValue(varKind)); return nodeInfoMirror; } - @Override - protected void createChildren(SpecializationData specialization) { - CodeTypeElement clazz = getElement(); - createConstructors(clazz); - - createExecuteMethods(specialization); - createCachedExecuteMethods(specialization); - - if (specialization.isUninitialized()) { - if (specialization.getNode().isFallbackReachable()) { - CodeVariableElement var = new CodeVariableElement(modifiers(Modifier.PRIVATE), context.getType(boolean.class), CONTAINS_FALLBACK); - var.addAnnotationMirror(new CodeAnnotationMirror(context.getTruffleTypes().getCompilationFinal())); - clazz.add(var); - } - clazz.add(createExecuteUninitialized()); - } - - if (!specialization.isUninitialized() && specialization.getNode().needsRewrites(context)) { - clazz.add(createCopyConstructorFactoryMethod(nodeGen.asType(), specialization)); - } else { - for (ExecutableElement constructor : ElementFilter.constructorsIn(clazz.getEnclosedElements())) { - if (constructor.getParameters().size() == 1 && ((CodeVariableElement) constructor.getParameters().get(0)).getType().equals(nodeGen.asType())) { - // skip copy constructor - not used - continue; - } - clazz.add(createConstructorFactoryMethod(specialization, constructor)); - } - } - } - protected void createConstructors(CodeTypeElement clazz) { TypeElement superTypeElement = ElementUtils.fromTypeMirror(clazz.getSuperclass()); - SpecializationData specialization = getModel(); - NodeData node = specialization.getNode(); for (ExecutableElement constructor : ElementFilter.constructorsIn(superTypeElement.getEnclosedElements())) { if (specialization.isUninitialized()) { // ignore copy constructors for uninitialized if not polymorphic @@ -223,7 +215,7 @@ } } - CodeExecutableElement superConstructor = createSuperConstructor(clazz, constructor); + CodeExecutableElement superConstructor = GeneratorUtils.createSuperConstructor(context, clazz, constructor); if (superConstructor == null) { continue; } @@ -232,9 +224,9 @@ builder.tree(body); if (superConstructor != null) { - for (Parameter param : getImplicitTypeParameters(getModel())) { - clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), getContext().getType(Class.class), implicitTypeName(param))); - superConstructor.getParameters().add(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(param))); + for (Parameter param : getImplicitTypeParameters(getSpecialization())) { + clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), context.getType(Class.class), implicitTypeName(param))); + superConstructor.getParameters().add(new CodeVariableElement(context.getType(Class.class), implicitTypeName(param))); builder.startStatement(); builder.string("this.").string(implicitTypeName(param)).string(" = ").string(implicitTypeName(param)); @@ -246,9 +238,7 @@ } } - protected void createExecuteMethods(SpecializationData specialization) { - NodeData node = specialization.getNode(); - CodeTypeElement clazz = getElement(); + protected void createExecuteMethods(CodeTypeElement clazz) { List primaryExecutes = null; int lastEvaluatedCount = -1; @@ -259,13 +249,13 @@ } if (execType.getEvaluatedCount() != lastEvaluatedCount) { lastEvaluatedCount = execType.getEvaluatedCount(); - primaryExecutes = findFunctionalExecutableType(specialization, lastEvaluatedCount); + primaryExecutes = findFunctionalExecutableType(lastEvaluatedCount); } CodeExecutableElement executeMethod = createExecutableTypeOverride(execType, true); clazz.add(executeMethod); CodeTreeBuilder builder = executeMethod.getBuilder(); - CodeTree result = createExecuteBody(builder, specialization, execType, primaryExecutes); + CodeTree result = createExecuteBody(builder, execType, primaryExecutes); if (result != null) { builder.tree(result); } else { @@ -274,17 +264,14 @@ } } - protected void createCachedExecuteMethods(SpecializationData specialization) { - NodeData node = specialization.getNode(); + protected void createCachedExecuteMethods(CodeTypeElement clazz) { if (!node.isPolymorphic(context)) { return; } - CodeTypeElement clazz = getElement(); - final SpecializationData polymorphic = node.getPolymorphicSpecialization(); ExecutableElement executeCached = nodeGen.getMethod(EXECUTE_CHAINED); - CodeExecutableElement executeMethod = CodeExecutableElement.clone(getContext().getEnvironment(), executeCached); + CodeExecutableElement executeMethod = CodeExecutableElement.clone(context.getEnvironment(), executeCached); executeMethod.getModifiers().remove(Modifier.ABSTRACT); CodeTreeBuilder builder = executeMethod.createBuilder(); @@ -325,14 +312,14 @@ return builder.getRoot(); } - private CodeTree createExecuteBody(CodeTreeBuilder parent, SpecializationData specialization, ExecutableTypeData execType, List primaryExecutes) { + private CodeTree createExecuteBody(CodeTreeBuilder parent, ExecutableTypeData execType, List primaryExecutes) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (primaryExecutes.contains(execType) || primaryExecutes.isEmpty()) { - builder.tree(createFunctionalExecute(builder, specialization, execType)); + builder.tree(createFunctionalExecute(builder, execType)); } else if (needsCastingExecuteMethod(execType)) { assert !primaryExecutes.isEmpty(); - builder.tree(createCastingExecute(builder, specialization, execType, primaryExecutes.get(0))); + builder.tree(createCastingExecute(builder, execType, primaryExecutes.get(0))); } else { return null; } @@ -341,7 +328,7 @@ } private CodeExecutableElement createExecutableTypeOverride(ExecutableTypeData execType, boolean evaluated) { - CodeExecutableElement method = CodeExecutableElement.clone(getContext().getEnvironment(), execType.getMethod()); + CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), execType.getMethod()); method.getAnnotationMirrors().clear(); for (VariableElement variable : method.getParameters()) { @@ -366,7 +353,7 @@ name = valueName(actualParameter); } - int varArgCount = getModel().getSignatureSize() - signatureIndex; + int varArgCount = getSpecialization().getSignatureSize() - signatureIndex; if (evaluated && actualParameter.isTypeVarArgs()) { Parameter baseVarArgs = actualParameter; name = valueName(baseVarArgs) + "Args"; @@ -411,7 +398,7 @@ return false; } - private List findFunctionalExecutableType(SpecializationData specialization, int evaluatedCount) { + private List findFunctionalExecutableType(int evaluatedCount) { TypeData primaryType = specialization.getReturnType().getTypeSystemType(); List otherTypes = specialization.getNode().getExecutableTypes(evaluatedCount); @@ -425,7 +412,7 @@ // no direct matches found use generic where the type is Object if (filteredTypes.isEmpty()) { for (ExecutableTypeData compareType : otherTypes) { - if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(getContext())) { + if (compareType.getType().isGeneric() && !compareType.hasUnexpectedValue(context)) { filteredTypes.add(compareType); } } @@ -442,7 +429,7 @@ return filteredTypes; } - private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final SpecializationData specialization, final ExecutableTypeData executable) { + private CodeTree createFunctionalExecute(CodeTreeBuilder parent, final ExecutableTypeData executable) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (specialization.isUninitialized()) { @@ -456,23 +443,21 @@ if (specialization.findNextSpecialization() != null) { CodeTreeBuilder returnBuilder = new CodeTreeBuilder(builder); returnBuilder.tree(createDeoptimize(builder)); - returnBuilder.tree(createCallRewriteMonomorphic(builder, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, "One of guards " + specialization.getGuards() + - " failed")); + returnBuilder.tree(createCallRewriteMonomorphic(builder, executable.hasUnexpectedValue(context), executable.getType(), null, "One of guards " + specialization.getGuards() + " failed")); returnSpecialized = returnBuilder.getRoot(); } builder.tree(createExecuteTree(builder, specialization, SpecializationGroup.create(specialization), new CodeBlock() { public CodeTree create(CodeTreeBuilder b, SpecializationData current) { - return createExecute(b, executable, specialization); + return createExecute(b, executable); } }, returnSpecialized, false, false, false, false)); return builder.getRoot(); } - private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable, SpecializationData specialization) { - NodeData node = specialization.getNode(); + private CodeTree createExecute(CodeTreeBuilder parent, ExecutableTypeData executable) { CodeTreeBuilder builder = new CodeTreeBuilder(parent); if (!specialization.getExceptions().isEmpty() || !specialization.getAssumptions().isEmpty()) { builder.startTryBlock(); @@ -494,7 +479,7 @@ addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null); returnBuilder.end(); } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { - emitEncounteredSynthetic(builder, getModel().getNode(), specialization); + emitEncounteredSynthetic(builder, getSpecialization().getNode(), specialization); } else { returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null)); } @@ -522,31 +507,30 @@ for (SpecializationThrowsData exception : specialization.getExceptions()) { builder.end().startCatchBlock(exception.getJavaClass(), "ex"); builder.tree(createDeoptimize(builder)); - builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, - "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass()))); + builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), null, "Thrown " + ElementUtils.getSimpleName(exception.getJavaClass()))); } builder.end(); } if (!specialization.getAssumptions().isEmpty()) { - builder.end().startCatchBlock(getContext().getTruffleTypes().getInvalidAssumption(), "ex"); - builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), specialization, null, "Assumption failed")); + builder.end().startCatchBlock(context.getTruffleTypes().getInvalidAssumption(), "ex"); + builder.tree(createCallRewriteMonomorphic(parent, executable.hasUnexpectedValue(context), executable.getType(), null, "Assumption failed")); builder.end(); } return builder.getRoot(); } - private CodeExecutableElement createCopyConstructorFactoryMethod(TypeMirror baseType, SpecializationData specialization) { + private CodeExecutableElement createCopyConstructorFactoryMethod(CodeTypeElement clazz, TypeMirror baseType) { List implicitTypeParams = getImplicitTypeParameters(specialization); String baseName = "current"; CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), NodeFactoryFactory.FACTORY_METHOD_NAME); method.addParameter(new CodeVariableElement(specialization.getNode().getNodeType(), baseName)); for (Parameter implicitTypeParam : implicitTypeParams) { - method.addParameter(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(implicitTypeParam))); + method.addParameter(new CodeVariableElement(context.getType(Class.class), implicitTypeName(implicitTypeParam))); } CodeTreeBuilder builder = method.createBuilder(); builder.startReturn(); - builder.startNew(getElement().asType()); + builder.startNew(clazz.asType()); builder.startGroup().cast(baseType, CodeTreeBuilder.singleString(baseName)).end(); for (Parameter param : implicitTypeParams) { builder.string(implicitTypeName(param)); @@ -555,13 +539,13 @@ return method; } - private CodeExecutableElement createConstructorFactoryMethod(SpecializationData specialization, ExecutableElement constructor) { + private CodeExecutableElement createConstructorFactoryMethod(CodeTypeElement clazz, ExecutableElement constructor) { List parameters = constructor.getParameters(); CodeExecutableElement method = new CodeExecutableElement(modifiers(STATIC), specialization.getNode().getNodeType(), NodeFactoryFactory.FACTORY_METHOD_NAME, parameters.toArray(new CodeVariableElement[parameters.size()])); CodeTreeBuilder builder = method.createBuilder(); builder.startReturn(); - builder.startNew(getElement().asType()); + builder.startNew(clazz.asType()); for (VariableElement param : parameters) { builder.string(((CodeVariableElement) param).getName()); } diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java Mon Dec 29 23:38:16 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/TypeSystemCodeGenerator.java Mon Dec 29 23:38:21 2014 +0100 @@ -29,11 +29,12 @@ import javax.lang.model.type.*; +import com.oracle.truffle.dsl.processor.*; import com.oracle.truffle.dsl.processor.java.*; import com.oracle.truffle.dsl.processor.java.model.*; import com.oracle.truffle.dsl.processor.model.*; -public class TypeSystemCodeGenerator extends AbstractCompilationUnitFactory { +public class TypeSystemCodeGenerator extends CodeTypeElementFactory { public static String isTypeMethodName(TypeData type) { return "is" + ElementUtils.getTypeId(type.getBoxedType()); @@ -69,20 +70,27 @@ } @Override - protected void createChildren(TypeSystemData m) { - add(new TypeClassFactory(), m); + public CodeTypeElement create(ProcessorContext context, TypeSystemData typeSystem) { + return new TypeClassFactory(context, typeSystem).create(); } - private static class TypeClassFactory extends AbstractClassElementFactory { + private static class TypeClassFactory { private static final String LOCAL_VALUE = "value"; - @Override - public CodeTypeElement create(TypeSystemData typeSystem) { + private final ProcessorContext context; + private final TypeSystemData typeSystem; + + public TypeClassFactory(ProcessorContext context, TypeSystemData typeSystem) { + this.context = context; + this.typeSystem = typeSystem; + } + + public CodeTypeElement create() { String name = typeName(typeSystem); - CodeTypeElement clazz = createClass(typeSystem, modifiers(PUBLIC, FINAL), name, typeSystem.getTemplateType().asType(), false); + CodeTypeElement clazz = GeneratorUtils.createClass(typeSystem, modifiers(PUBLIC, FINAL), name, typeSystem.getTemplateType().asType(), false); - clazz.add(createConstructorUsingFields(modifiers(PROTECTED), clazz)); + clazz.add(GeneratorUtils.createConstructorUsingFields(context, modifiers(PROTECTED), clazz)); CodeVariableElement singleton = createSingleton(clazz); clazz.add(singleton); @@ -120,21 +128,20 @@ } private CodeVariableElement createSingleton(CodeTypeElement clazz) { - CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(getModel())); + CodeVariableElement field = new CodeVariableElement(modifiers(PUBLIC, STATIC, FINAL), clazz.asType(), singletonName(typeSystem)); field.createInitBuilder().startNew(clazz.asType()).end(); return field; } private CodeExecutableElement createIsImplicitTypeMethod(TypeData type, boolean typed) { - TypeSystemData typeSystem = getModel(); List casts = typeSystem.lookupByTargetType(type); if (casts.isEmpty()) { return null; } - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type)); - method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), TypeSystemCodeGenerator.isImplicitTypeMethodName(type)); + method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); if (typed) { - method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "typeHint")); + method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint")); } CodeTreeBuilder builder = method.createBuilder(); @@ -165,15 +172,14 @@ } private CodeExecutableElement createAsImplicitTypeMethod(TypeData type, boolean typed) { - TypeSystemData typeSystem = getModel(); List casts = typeSystem.lookupByTargetType(type); if (casts.isEmpty()) { return null; } CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asImplicitTypeMethodName(type)); - method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); + method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); if (typed) { - method.addParameter(new CodeVariableElement(getContext().getType(Class.class), "typeHint")); + method.addParameter(new CodeVariableElement(context.getType(Class.class), "typeHint")); } List sourceTypes = typeSystem.lookupSourceTypes(type); @@ -204,20 +210,19 @@ } builder.startElseBlock(); - builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end(); - builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); + builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end(); + builder.startThrow().startNew(context.getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); builder.end(); return method; } private CodeExecutableElement createGetTypeIndex(TypeData type) { - TypeSystemData typeSystem = getModel(); List casts = typeSystem.lookupByTargetType(type); if (casts.isEmpty()) { return null; } - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type)); - method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(Class.class), TypeSystemCodeGenerator.getImplicitClass(type)); + method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); List sourceTypes = typeSystem.lookupSourceTypes(type); CodeTreeBuilder builder = method.createBuilder(); @@ -231,8 +236,8 @@ } builder.startElseBlock(); - builder.startStatement().startStaticCall(getContext().getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end(); - builder.startThrow().startNew(getContext().getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); + builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerDirectives(), "transferToInterpreterAndInvalidate").end().end(); + builder.startThrow().startNew(context.getType(IllegalArgumentException.class)).doubleQuote("Illegal type ").end().end(); builder.end(); return method; @@ -243,10 +248,10 @@ return null; } - CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), getContext().getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type)); - method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); + CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getType(boolean.class), TypeSystemCodeGenerator.isTypeMethodName(type)); + method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); - DeclaredType suppressWarnings = (DeclaredType) getContext().getType(SuppressWarnings.class); + DeclaredType suppressWarnings = (DeclaredType) context.getType(SuppressWarnings.class); CodeAnnotationMirror annotationMirror = new CodeAnnotationMirror(suppressWarnings); annotationMirror.setElementValue(annotationMirror.findExecutableElement("value"), new CodeAnnotationValue("static-method")); method.getAnnotationMirrors().add(annotationMirror); @@ -263,10 +268,10 @@ } CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), type.getPrimitiveType(), TypeSystemCodeGenerator.asTypeMethodName(type)); - method.addParameter(new CodeVariableElement(getContext().getType(Object.class), LOCAL_VALUE)); + method.addParameter(new CodeVariableElement(context.getType(Object.class), LOCAL_VALUE)); CodeTreeBuilder body = method.createBuilder(); - String assertMessage = typeName(getModel()) + "." + asTypeMethodName(type) + ": " + ElementUtils.getSimpleName(type.getBoxedType()) + " expected"; + String assertMessage = typeName(typeSystem) + "." + asTypeMethodName(type) + ": " + ElementUtils.getSimpleName(type.getBoxedType()) + " expected"; body.startAssert().startCall(isTypeMethodName(type)).string(LOCAL_VALUE).end().string(" : ").doubleQuote(assertMessage).end(); body.startReturn().cast(type.getPrimitiveType(), body.create().string(LOCAL_VALUE).getTree()).end(); @@ -276,13 +281,13 @@ private CodeExecutableElement createExpectTypeMethod(TypeData expectedType, TypeData sourceType) { CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), expectedType.getPrimitiveType(), TypeSystemCodeGenerator.expectTypeMethodName(expectedType)); method.addParameter(new CodeVariableElement(sourceType.getPrimitiveType(), LOCAL_VALUE)); - method.addThrownType(getContext().getTruffleTypes().getUnexpectedValueException()); + method.addThrownType(context.getTruffleTypes().getUnexpectedValueException()); CodeTreeBuilder body = method.createBuilder(); body.startIf().startCall(TypeSystemCodeGenerator.isTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end().startBlock(); body.startReturn().startCall(TypeSystemCodeGenerator.asTypeMethodName(expectedType)).string(LOCAL_VALUE).end().end(); body.end(); // if-block - body.startThrow().startNew(getContext().getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end(); + body.startThrow().startNew(context.getTruffleTypes().getUnexpectedValueException()).string(LOCAL_VALUE).end().end(); return method; } diff -r 1acaa69ff61b -r f6b8787dc113 graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTypeElement.java --- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTypeElement.java Mon Dec 29 23:38:16 2014 +0100 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/java/model/CodeTypeElement.java Mon Dec 29 23:38:21 2014 +0100 @@ -108,7 +108,7 @@ } public boolean isTopLevelClass() { - return super.getEnclosingElement() instanceof CodeCompilationUnit; + return super.getEnclosingElement() instanceof CodeCompilationUnit || super.getEnclosingElement() == null; } private Name createQualifiedName() {