Mercurial > hg > truffle
diff graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java @ 12392:4e26955b6da2
Truffle-DSL: new implicit cast code generation layout supports now executeWith.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Thu, 03 Oct 2013 18:07:59 +0200 |
parents | 7aa2a8c69ba3 |
children | 8e8347ecabbc |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Thu Oct 03 16:31:09 2013 +0200 +++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java Thu Oct 03 18:07:59 2013 +0200 @@ -42,7 +42,6 @@ import com.oracle.truffle.dsl.processor.template.*; import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature; import com.oracle.truffle.dsl.processor.typesystem.*; -import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBaseIterators.*; public class NodeCodeGenerator extends CompilationUnitFactory<NodeData> { @@ -954,7 +953,7 @@ } } - for (CodeExecutableElement method : createImplicitChildrenAccessors(node, clazz)) { + for (CodeExecutableElement method : createImplicitChildrenAccessors()) { clazz.add(method); } @@ -967,7 +966,8 @@ } } - private List<CodeExecutableElement> createImplicitChildrenAccessors(NodeData node, CodeTypeElement clazz) { + private List<CodeExecutableElement> createImplicitChildrenAccessors() { + NodeData node = getModel().getNode(); List<CodeExecutableElement> methods = new ArrayList<>(); Map<NodeChildData, Set<TypeData>> expectTypes = new HashMap<>(); for (ExecutableTypeData executableType : node.getExecutableTypes()) { @@ -2018,14 +2018,22 @@ builder.end(); } else { + List<TypeData> sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); TypeData expectType = sourceParameter != null ? sourceParameter.getTypeSystemType() : null; - builder.tree(createExecuteExpression(parent, child, expectType, targetExecutable, param, unexpectedParameter, null)); + if (sourceTypes.size() > 1) { + builder.tree(createExecuteExpressions(parent, param, expectType)); + } else { + builder.tree(createExecuteExpression(parent, child, expectType, targetExecutable, param, unexpectedParameter, null)); + } } return builder.getRoot(); } private String createExecuteChildMethodName(ActualParameter param, boolean expect) { NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); + if (child.getExecuteWith().size() > 0) { + return null; + } List<TypeData> sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); if (sourceTypes.size() <= 1) { return null; @@ -2057,53 +2065,56 @@ return null; } - NodeData node = getModel().getNode(); - NodeChildData child = node.findChild(param.getSpecification().getName()); - List<TypeData> sourceTypes = node.getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); - assert sourceTypes.size() >= 1; - 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")); if (expectType != null) { method.addParameter(new CodeVariableElement(expectType.getPrimitiveType(), valueNameEvaluated(param))); } method.addParameter(new CodeVariableElement(getContext().getType(Class.class), typeName(param))); + CodeTreeBuilder builder = method.createBuilder(); - builder.declaration(param.getType(), valueName(param)); - - boolean unexpected = false; + builder.tree(createExecuteExpressions(builder, param, expectType)); + builder.startReturn().string(valueName(param)).end(); + + return method; + } + + private CodeTree createExecuteExpressions(CodeTreeBuilder parent, ActualParameter param, TypeData expectType) { + CodeTreeBuilder builder = parent.create(); + NodeData node = getModel().getNode(); + NodeChildData child = node.findChild(param.getSpecification().getName()); + List<TypeData> sourceTypes = node.getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); boolean elseIf = false; int index = 0; - for (TypeData typeData : sourceTypes) { + for (TypeData sourceType : sourceTypes) { if (index < sourceTypes.size() - 1) { elseIf = builder.startIf(elseIf); - builder.string(typeName(param)).string(" == ").typeLiteral(typeData.getPrimitiveType()); + builder.string(typeName(param)).string(" == ").typeLiteral(sourceType.getPrimitiveType()); builder.end(); builder.startBlock(); } else { builder.startElseBlock(); } - ExecutableTypeData implictExecutableTypeData = child.getNodeData().findExecutableType(typeData, child.getExecuteWith().size()); - if (!unexpected && implictExecutableTypeData.hasUnexpectedValue(getContext())) { - unexpected = true; + ExecutableTypeData implictExecutableTypeData = child.getNodeData().findExecutableType(sourceType, child.getExecuteWith().size()); + if (implictExecutableTypeData == null) { + /* + * For children with executeWith.size() > 0 an executable type may not exist so + * use the generic executable type which is guaranteed to exist. An expect call + * is inserted automatically by #createExecuteExpression. + */ + implictExecutableTypeData = child.getNodeData().findExecutableType(node.getTypeSystem().getGenericTypeData(), child.getExecuteWith().size()); } - ImplicitCastData cast = child.getNodeData().getTypeSystem().lookupCast(typeData, param.getTypeSystemType()); + + ImplicitCastData cast = child.getNodeData().getTypeSystem().lookupCast(sourceType, param.getTypeSystemType()); CodeTree execute = createExecuteExpression(builder, child, expectType, implictExecutableTypeData, param, null, cast); builder.statement(execute); builder.end(); index++; } - - builder.startReturn().string(valueName(param)).end(); - - if (unexpected) { - method.getThrownTypes().add(getContext().getTruffleTypes().getUnexpectedValueException()); - } - - return method; + return builder.getRoot(); } private CodeTree createExecuteExpression(CodeTreeBuilder parent, NodeChildData child, TypeData expectType, ExecutableTypeData targetExecutable, ActualParameter targetParameter, @@ -2115,8 +2126,13 @@ startCallTypeSystemMethod(getContext(), builder, child.getNodeData(), cast.getMethodName()); } - if (targetExecutable.getType().needsCastTo(context, targetParameter.getTypeSystemType()) && cast == null) { - startCallTypeSystemMethod(getContext(), builder, child.getNodeData(), TypeSystemCodeGenerator.expectTypeMethodName(targetParameter.getTypeSystemType())); + TypeData expectTarget = targetParameter.getTypeSystemType(); + if (cast != null) { + expectTarget = cast.getSourceType(); + } + + if (targetExecutable.getType().needsCastTo(context, expectTarget)) { + startCallTypeSystemMethod(getContext(), builder, child.getNodeData(), TypeSystemCodeGenerator.expectTypeMethodName(expectTarget)); } NodeData node = getModel().getNode();