Mercurial > hg > graal-compiler
comparison 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 |
comparison
equal
deleted
inserted
replaced
12391:7aa2a8c69ba3 | 12392:4e26955b6da2 |
---|---|
40 import com.oracle.truffle.dsl.processor.node.NodeChildData.ExecutionKind; | 40 import com.oracle.truffle.dsl.processor.node.NodeChildData.ExecutionKind; |
41 import com.oracle.truffle.dsl.processor.node.SpecializationGroup.TypeGuard; | 41 import com.oracle.truffle.dsl.processor.node.SpecializationGroup.TypeGuard; |
42 import com.oracle.truffle.dsl.processor.template.*; | 42 import com.oracle.truffle.dsl.processor.template.*; |
43 import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature; | 43 import com.oracle.truffle.dsl.processor.template.TemplateMethod.Signature; |
44 import com.oracle.truffle.dsl.processor.typesystem.*; | 44 import com.oracle.truffle.dsl.processor.typesystem.*; |
45 import com.sun.org.apache.xml.internal.dtm.ref.DTMDefaultBaseIterators.*; | |
46 | 45 |
47 public class NodeCodeGenerator extends CompilationUnitFactory<NodeData> { | 46 public class NodeCodeGenerator extends CompilationUnitFactory<NodeData> { |
48 | 47 |
49 private static final String THIS_NODE_LOCAL_VAR_NAME = "thisNode"; | 48 private static final String THIS_NODE_LOCAL_VAR_NAME = "thisNode"; |
50 | 49 |
952 } | 951 } |
953 clazz.add(createCachedExecute(node, polymorph, genericCachedExecute)); | 952 clazz.add(createCachedExecute(node, polymorph, genericCachedExecute)); |
954 } | 953 } |
955 } | 954 } |
956 | 955 |
957 for (CodeExecutableElement method : createImplicitChildrenAccessors(node, clazz)) { | 956 for (CodeExecutableElement method : createImplicitChildrenAccessors()) { |
958 clazz.add(method); | 957 clazz.add(method); |
959 } | 958 } |
960 | 959 |
961 clazz.add(createGenericExecuteAndSpecialize(node, rootGroup)); | 960 clazz.add(createGenericExecuteAndSpecialize(node, rootGroup)); |
962 clazz.add(createInfoMessage(node)); | 961 clazz.add(createInfoMessage(node)); |
965 if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) { | 964 if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) { |
966 clazz.add(createGenericExecute(node, rootGroup)); | 965 clazz.add(createGenericExecute(node, rootGroup)); |
967 } | 966 } |
968 } | 967 } |
969 | 968 |
970 private List<CodeExecutableElement> createImplicitChildrenAccessors(NodeData node, CodeTypeElement clazz) { | 969 private List<CodeExecutableElement> createImplicitChildrenAccessors() { |
970 NodeData node = getModel().getNode(); | |
971 List<CodeExecutableElement> methods = new ArrayList<>(); | 971 List<CodeExecutableElement> methods = new ArrayList<>(); |
972 Map<NodeChildData, Set<TypeData>> expectTypes = new HashMap<>(); | 972 Map<NodeChildData, Set<TypeData>> expectTypes = new HashMap<>(); |
973 for (ExecutableTypeData executableType : node.getExecutableTypes()) { | 973 for (ExecutableTypeData executableType : node.getExecutableTypes()) { |
974 for (int i = 0; i < executableType.getEvaluatedCount(); i++) { | 974 for (int i = 0; i < executableType.getEvaluatedCount(); i++) { |
975 ActualParameter parameter = executableType.getSignatureParameter(i); | 975 ActualParameter parameter = executableType.getSignatureParameter(i); |
2016 | 2016 |
2017 builder.string(typeName(param)); | 2017 builder.string(typeName(param)); |
2018 | 2018 |
2019 builder.end(); | 2019 builder.end(); |
2020 } else { | 2020 } else { |
2021 List<TypeData> sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); | |
2021 TypeData expectType = sourceParameter != null ? sourceParameter.getTypeSystemType() : null; | 2022 TypeData expectType = sourceParameter != null ? sourceParameter.getTypeSystemType() : null; |
2022 builder.tree(createExecuteExpression(parent, child, expectType, targetExecutable, param, unexpectedParameter, null)); | 2023 if (sourceTypes.size() > 1) { |
2024 builder.tree(createExecuteExpressions(parent, param, expectType)); | |
2025 } else { | |
2026 builder.tree(createExecuteExpression(parent, child, expectType, targetExecutable, param, unexpectedParameter, null)); | |
2027 } | |
2023 } | 2028 } |
2024 return builder.getRoot(); | 2029 return builder.getRoot(); |
2025 } | 2030 } |
2026 | 2031 |
2027 private String createExecuteChildMethodName(ActualParameter param, boolean expect) { | 2032 private String createExecuteChildMethodName(ActualParameter param, boolean expect) { |
2028 NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); | 2033 NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); |
2034 if (child.getExecuteWith().size() > 0) { | |
2035 return null; | |
2036 } | |
2029 List<TypeData> sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); | 2037 List<TypeData> sourceTypes = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); |
2030 if (sourceTypes.size() <= 1) { | 2038 if (sourceTypes.size() <= 1) { |
2031 return null; | 2039 return null; |
2032 } | 2040 } |
2033 String prefix = expect ? "expect" : "execute"; | 2041 String prefix = expect ? "expect" : "execute"; |
2055 String childExecuteName = createExecuteChildMethodName(param, expectType != null); | 2063 String childExecuteName = createExecuteChildMethodName(param, expectType != null); |
2056 if (childExecuteName == null) { | 2064 if (childExecuteName == null) { |
2057 return null; | 2065 return null; |
2058 } | 2066 } |
2059 | 2067 |
2068 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, expectType != null ? STATIC : FINAL), param.getType(), childExecuteName); | |
2069 method.getThrownTypes().add(getContext().getTruffleTypes().getUnexpectedValueException()); | |
2070 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); | |
2071 if (expectType != null) { | |
2072 method.addParameter(new CodeVariableElement(expectType.getPrimitiveType(), valueNameEvaluated(param))); | |
2073 } | |
2074 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), typeName(param))); | |
2075 | |
2076 CodeTreeBuilder builder = method.createBuilder(); | |
2077 builder.declaration(param.getType(), valueName(param)); | |
2078 builder.tree(createExecuteExpressions(builder, param, expectType)); | |
2079 builder.startReturn().string(valueName(param)).end(); | |
2080 | |
2081 return method; | |
2082 } | |
2083 | |
2084 private CodeTree createExecuteExpressions(CodeTreeBuilder parent, ActualParameter param, TypeData expectType) { | |
2085 CodeTreeBuilder builder = parent.create(); | |
2060 NodeData node = getModel().getNode(); | 2086 NodeData node = getModel().getNode(); |
2061 NodeChildData child = node.findChild(param.getSpecification().getName()); | 2087 NodeChildData child = node.findChild(param.getSpecification().getName()); |
2062 List<TypeData> sourceTypes = node.getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); | 2088 List<TypeData> sourceTypes = node.getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); |
2063 assert sourceTypes.size() >= 1; | |
2064 | |
2065 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, expectType != null ? STATIC : FINAL), param.getType(), childExecuteName); | |
2066 | |
2067 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); | |
2068 if (expectType != null) { | |
2069 method.addParameter(new CodeVariableElement(expectType.getPrimitiveType(), valueNameEvaluated(param))); | |
2070 } | |
2071 method.addParameter(new CodeVariableElement(getContext().getType(Class.class), typeName(param))); | |
2072 CodeTreeBuilder builder = method.createBuilder(); | |
2073 | |
2074 builder.declaration(param.getType(), valueName(param)); | |
2075 | |
2076 boolean unexpected = false; | |
2077 boolean elseIf = false; | 2089 boolean elseIf = false; |
2078 int index = 0; | 2090 int index = 0; |
2079 for (TypeData typeData : sourceTypes) { | 2091 for (TypeData sourceType : sourceTypes) { |
2080 if (index < sourceTypes.size() - 1) { | 2092 if (index < sourceTypes.size() - 1) { |
2081 elseIf = builder.startIf(elseIf); | 2093 elseIf = builder.startIf(elseIf); |
2082 builder.string(typeName(param)).string(" == ").typeLiteral(typeData.getPrimitiveType()); | 2094 builder.string(typeName(param)).string(" == ").typeLiteral(sourceType.getPrimitiveType()); |
2083 builder.end(); | 2095 builder.end(); |
2084 builder.startBlock(); | 2096 builder.startBlock(); |
2085 } else { | 2097 } else { |
2086 builder.startElseBlock(); | 2098 builder.startElseBlock(); |
2087 } | 2099 } |
2088 | 2100 |
2089 ExecutableTypeData implictExecutableTypeData = child.getNodeData().findExecutableType(typeData, child.getExecuteWith().size()); | 2101 ExecutableTypeData implictExecutableTypeData = child.getNodeData().findExecutableType(sourceType, child.getExecuteWith().size()); |
2090 if (!unexpected && implictExecutableTypeData.hasUnexpectedValue(getContext())) { | 2102 if (implictExecutableTypeData == null) { |
2091 unexpected = true; | 2103 /* |
2092 } | 2104 * For children with executeWith.size() > 0 an executable type may not exist so |
2093 ImplicitCastData cast = child.getNodeData().getTypeSystem().lookupCast(typeData, param.getTypeSystemType()); | 2105 * use the generic executable type which is guaranteed to exist. An expect call |
2106 * is inserted automatically by #createExecuteExpression. | |
2107 */ | |
2108 implictExecutableTypeData = child.getNodeData().findExecutableType(node.getTypeSystem().getGenericTypeData(), child.getExecuteWith().size()); | |
2109 } | |
2110 | |
2111 ImplicitCastData cast = child.getNodeData().getTypeSystem().lookupCast(sourceType, param.getTypeSystemType()); | |
2094 CodeTree execute = createExecuteExpression(builder, child, expectType, implictExecutableTypeData, param, null, cast); | 2112 CodeTree execute = createExecuteExpression(builder, child, expectType, implictExecutableTypeData, param, null, cast); |
2095 builder.statement(execute); | 2113 builder.statement(execute); |
2096 builder.end(); | 2114 builder.end(); |
2097 index++; | 2115 index++; |
2098 } | 2116 } |
2099 | 2117 return builder.getRoot(); |
2100 builder.startReturn().string(valueName(param)).end(); | |
2101 | |
2102 if (unexpected) { | |
2103 method.getThrownTypes().add(getContext().getTruffleTypes().getUnexpectedValueException()); | |
2104 } | |
2105 | |
2106 return method; | |
2107 } | 2118 } |
2108 | 2119 |
2109 private CodeTree createExecuteExpression(CodeTreeBuilder parent, NodeChildData child, TypeData expectType, ExecutableTypeData targetExecutable, ActualParameter targetParameter, | 2120 private CodeTree createExecuteExpression(CodeTreeBuilder parent, NodeChildData child, TypeData expectType, ExecutableTypeData targetExecutable, ActualParameter targetParameter, |
2110 ActualParameter unexpectedParameter, ImplicitCastData cast) { | 2121 ActualParameter unexpectedParameter, ImplicitCastData cast) { |
2111 CodeTreeBuilder builder = parent.create(); | 2122 CodeTreeBuilder builder = parent.create(); |
2113 builder.string(" = "); | 2124 builder.string(" = "); |
2114 if (cast != null) { | 2125 if (cast != null) { |
2115 startCallTypeSystemMethod(getContext(), builder, child.getNodeData(), cast.getMethodName()); | 2126 startCallTypeSystemMethod(getContext(), builder, child.getNodeData(), cast.getMethodName()); |
2116 } | 2127 } |
2117 | 2128 |
2118 if (targetExecutable.getType().needsCastTo(context, targetParameter.getTypeSystemType()) && cast == null) { | 2129 TypeData expectTarget = targetParameter.getTypeSystemType(); |
2119 startCallTypeSystemMethod(getContext(), builder, child.getNodeData(), TypeSystemCodeGenerator.expectTypeMethodName(targetParameter.getTypeSystemType())); | 2130 if (cast != null) { |
2131 expectTarget = cast.getSourceType(); | |
2132 } | |
2133 | |
2134 if (targetExecutable.getType().needsCastTo(context, expectTarget)) { | |
2135 startCallTypeSystemMethod(getContext(), builder, child.getNodeData(), TypeSystemCodeGenerator.expectTypeMethodName(expectTarget)); | |
2120 } | 2136 } |
2121 | 2137 |
2122 NodeData node = getModel().getNode(); | 2138 NodeData node = getModel().getNode(); |
2123 if (expectType == null) { | 2139 if (expectType == null) { |
2124 builder.tree(createExecuteChildExpression(builder, child, targetParameter, targetExecutable, unexpectedParameter)); | 2140 builder.tree(createExecuteChildExpression(builder, child, targetParameter, targetExecutable, unexpectedParameter)); |