Mercurial > hg > graal-jvmci-8
diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeBaseFactory.java @ 18753:f6b8787dc113
Truffle-DSL: replace complex factory system with a much simpler version
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Mon, 29 Dec 2014 23:38:21 +0100 |
parents | 1acaa69ff61b |
children | 59bf50cc5a32 |
line wrap: on
line diff
--- 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<SpecializationData> { +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<ExecutableElement> findUserConstructors(TypeMirror nodeType) { List<ExecutableElement> 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<NodeExecutionData> 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<CodeExecutableElement> createImplicitChildrenAccessors() { - NodeData node = getModel().getNode(); List<Set<TypeData>> prototype = Collections.nCopies(node.getGenericSpecialization().getParameters().size(), null); List<Set<TypeData>> 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<ExecutableElement> 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<TypeData> types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + List<TypeData> 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<TypeData> types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + List<TypeData> 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<TypeData> types = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + List<TypeData> 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<Parameter> 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<Parameter> targetParameters, + protected CodeTree createExecuteChildren(CodeTreeBuilder parent, ExecutableTypeData sourceExecutable, SpecializationData currentSpecialization, List<Parameter> 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<TypeData> possiblePolymorphicTypes = lookupPolymorphicTargetTypes(targetParameter); if (possiblePolymorphicTypes.size() > 1) { @@ -1242,7 +1237,6 @@ } private final List<TypeData> lookupPolymorphicTargetTypes(Parameter param) { - SpecializationData specialization = getModel(); Set<TypeData> 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<TypeData> 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<TypeData> polymorphicTargetTypes = lookupPolymorphicTargetTypes(targetParameter); if (polymorphicTargetTypes.size() > 1) { @@ -1467,7 +1460,7 @@ } private boolean hasUnexpectedType(NodeExecutionData execution, Parameter sourceParameter, TypeData targetType) { - List<TypeData> implicitSourceTypes = getModel().getNode().getTypeSystem().lookupSourceTypes(targetType); + List<TypeData> 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<Parameter> 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<Parameter> specializationParams = getModel().findParameters(spec); + ParameterSpec spec = getSpecialization().getSpecification().findParameterSpec(child.getName()); + List<Parameter> 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<T> {