comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java @ 12567:0d3e4d940925

Truffle-DSL: fixed recursive rewrite problem for transitions from monomorphic to polymorphic. (GRAAL-560 #resolve)
author Christian Humer <christian.humer@gmail.com>
date Thu, 24 Oct 2013 16:01:44 +0200
parents d7f8dd4fe876
children ba6593e52d22
comparison
equal deleted inserted replaced
12566:c17bfad2fa98 12567:0d3e4d940925
962 } 962 }
963 963
964 for (CodeExecutableElement method : createImplicitChildrenAccessors()) { 964 for (CodeExecutableElement method : createImplicitChildrenAccessors()) {
965 clazz.add(method); 965 clazz.add(method);
966 } 966 }
967
968 clazz.add(createGenericExecuteAndSpecialize(node, rootGroup)); 967 clazz.add(createGenericExecuteAndSpecialize(node, rootGroup));
969 clazz.add(createInfoMessage(node)); 968 clazz.add(createInfoMessage(node));
970 } 969 }
971 970
971 if (needsInvokeCopyConstructorMethod()) {
972 clazz.add(createInvokeCopyConstructor(clazz.asType(), null));
973 clazz.add(createCopyPolymorphicConstructor(clazz.asType()));
974 }
975
972 if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) { 976 if (node.getGenericSpecialization() != null && node.getGenericSpecialization().isReachable()) {
973 clazz.add(createGenericExecute(node, rootGroup)); 977 clazz.add(createGenericExecute(node, rootGroup));
974 } 978 }
979 }
980
981 protected boolean needsInvokeCopyConstructorMethod() {
982 return getModel().getNode().isPolymorphic();
983 }
984
985 protected CodeExecutableElement createInvokeCopyConstructor(TypeMirror baseType, SpecializationData specialization) {
986 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), baseType, "invokeCopyConstructor");
987 if (specialization == null) {
988 method.getModifiers().add(ABSTRACT);
989 } else {
990 CodeTreeBuilder builder = method.createBuilder();
991 builder.startReturn();
992 builder.startNew(getElement().asType());
993 builder.string("this");
994 for (ActualParameter param : getImplicitTypeParamters(specialization)) {
995 builder.string(implicitTypeName(param));
996 }
997 builder.end().end();
998 }
999 return method;
1000 }
1001
1002 protected CodeExecutableElement createCopyPolymorphicConstructor(TypeMirror baseType) {
1003 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), baseType, "copyPolymorphic");
1004 CodeTreeBuilder builder = method.createBuilder();
1005 CodeTreeBuilder nullBuilder = builder.create();
1006 CodeTreeBuilder oldBuilder = builder.create();
1007 CodeTreeBuilder resetBuilder = builder.create();
1008
1009 for (ActualParameter param : getModel().getParameters()) {
1010 if (!param.getSpecification().isSignature()) {
1011 continue;
1012 }
1013 NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName());
1014
1015 CodeTreeBuilder access = builder.create();
1016 access.string("this.").string(child.getName());
1017 if (child.getCardinality().isMany()) {
1018 access.string("[").string(String.valueOf(param.getIndex())).string("]");
1019 }
1020
1021 String oldName = "old" + Utils.firstLetterUpperCase(param.getLocalName());
1022 oldBuilder.declaration(child.getNodeData().getNodeType(), oldName, access);
1023 nullBuilder.startStatement().tree(access.getRoot()).string(" = null").end();
1024 resetBuilder.startStatement().tree(access.getRoot()).string(" = ").string(oldName).end();
1025 }
1026
1027 builder.tree(oldBuilder.getRoot());
1028 builder.tree(nullBuilder.getRoot());
1029
1030 builder.startStatement().type(baseType).string(" copy = ");
1031 builder.startCall("invokeCopyConstructor").end();
1032 builder.end();
1033
1034 builder.tree(resetBuilder.getRoot());
1035 builder.startReturn().string("copy").end();
1036 return method;
975 } 1037 }
976 1038
977 private List<CodeExecutableElement> createImplicitChildrenAccessors() { 1039 private List<CodeExecutableElement> createImplicitChildrenAccessors() {
978 NodeData node = getModel().getNode(); 1040 NodeData node = getModel().getNode();
979 // Map<NodeChildData, Set<TypeData>> expectTypes = new HashMap<>(); 1041 // Map<NodeChildData, Set<TypeData>> expectTypes = new HashMap<>();
1793 private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) { 1855 private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) {
1794 String polyClassName = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization()); 1856 String polyClassName = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization());
1795 String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization()); 1857 String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization());
1796 CodeTreeBuilder builder = parent.create(); 1858 CodeTreeBuilder builder = parent.create();
1797 1859
1860 builder.declaration(getElement().asType(), "currentCopy", currentNode + ".copyPolymorphic()");
1798 builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string(currentNode).end()); 1861 builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string(currentNode).end());
1799
1800 for (ActualParameter param : node.getGenericSpecialization().getParameters()) {
1801 if (!param.getSpecification().isSignature()) {
1802 continue;
1803 }
1804 NodeChildData child = node.findChild(param.getSpecification().getName());
1805 if (child != null) {
1806 builder.startStatement().string(currentNode).string(".").string(child.getName());
1807 if (child.getCardinality().isMany()) {
1808 builder.string("[").string(String.valueOf(param.getIndex())).string("]");
1809 }
1810 builder.string(" = null").end();
1811 }
1812 }
1813 builder.startStatement().startCall(currentNode, "replace").string("polymorphic").string("message").end().end(); 1862 builder.startStatement().startCall(currentNode, "replace").string("polymorphic").string("message").end().end();
1814 builder.startStatement().startCall("polymorphic", "setNext0").string(currentNode).end().end(); 1863 builder.startStatement().startCall("polymorphic", "setNext0").string("currentCopy").end().end();
1815 builder.startStatement().startCall(currentNode, "setNext0").startNew(uninitializedName).string(currentNode).end().end().end(); 1864 builder.startStatement().startCall("currentCopy", "setNext0").startNew(uninitializedName).string(currentNode).end().end().end();
1816 1865
1817 builder.startReturn(); 1866 builder.startReturn();
1818 builder.startCall(currentNode + ".next0", executeCachedName(node.getGenericPolymorphicSpecialization())); 1867 builder.startCall("currentCopy.next0", executeCachedName(node.getGenericPolymorphicSpecialization()));
1819 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, true, null); 1868 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, true, null);
1820 builder.end(); 1869 builder.end();
1821 builder.end(); 1870 builder.end();
1822 1871
1823 return builder.getRoot(); 1872 return builder.getRoot();
1977 2026
1978 return builder.getRoot(); 2027 return builder.getRoot();
1979 } else { 2028 } else {
1980 return createExecuteChildImplicit(parent, child, sourceExecutable, targetParameter, unexpectedParameter); 2029 return createExecuteChildImplicit(parent, child, sourceExecutable, targetParameter, unexpectedParameter);
1981 } 2030 }
2031 }
2032
2033 protected final List<ActualParameter> getImplicitTypeParamters(SpecializationData model) {
2034 List<ActualParameter> parameter = new ArrayList<>();
2035 for (ActualParameter param : model.getParameters()) {
2036 if (!param.getSpecification().isSignature()) {
2037 continue;
2038 }
2039 NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName());
2040 List<TypeData> types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType());
2041 if (types.size() > 1) {
2042 parameter.add(param);
2043 }
2044 }
2045 return parameter;
1982 } 2046 }
1983 2047
1984 protected final TreeSet<TypeData> lookupPolymorphicTargetTypes(ActualParameter param) { 2048 protected final TreeSet<TypeData> lookupPolymorphicTargetTypes(ActualParameter param) {
1985 SpecializationData specialization = getModel(); 2049 SpecializationData specialization = getModel();
1986 TreeSet<TypeData> possiblePolymorphicTypes = new TreeSet<>(); 2050 TreeSet<TypeData> possiblePolymorphicTypes = new TreeSet<>();
2527 continue; 2591 continue;
2528 } 2592 }
2529 getElement().add(createUpdateType(parameter)); 2593 getElement().add(createUpdateType(parameter));
2530 } 2594 }
2531 2595
2596 if (needsInvokeCopyConstructorMethod()) {
2597 clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization));
2598 }
2599
2532 createCachedExecuteMethods(specialization); 2600 createCachedExecuteMethods(specialization);
2533 2601
2534 } 2602 }
2535 2603
2536 private ExecutableElement createUpdateType(ActualParameter parameter) { 2604 private ExecutableElement createUpdateType(ActualParameter parameter) {
2604 2672
2605 createExecuteMethods(specialization); 2673 createExecuteMethods(specialization);
2606 createCachedExecuteMethods(specialization); 2674 createCachedExecuteMethods(specialization);
2607 if (specialization.getNode().isPolymorphic()) { 2675 if (specialization.getNode().isPolymorphic()) {
2608 getElement().add(createUpdateTypes(nodeGen.asType())); 2676 getElement().add(createUpdateTypes(nodeGen.asType()));
2677 }
2678 if (needsInvokeCopyConstructorMethod()) {
2679 clazz.add(createInvokeCopyConstructor(nodeGen.asType(), specialization));
2609 } 2680 }
2610 } 2681 }
2611 2682
2612 protected void createConstructors(CodeTypeElement clazz) { 2683 protected void createConstructors(CodeTypeElement clazz) {
2613 TypeElement superTypeElement = Utils.fromTypeMirror(clazz.getSuperclass()); 2684 TypeElement superTypeElement = Utils.fromTypeMirror(clazz.getSuperclass());
2634 if (superConstructor != null) { 2705 if (superConstructor != null) {
2635 if (getModel().isGeneric() && node.isPolymorphic()) { 2706 if (getModel().isGeneric() && node.isPolymorphic()) {
2636 builder.statement("this.next0 = null"); 2707 builder.statement("this.next0 = null");
2637 } 2708 }
2638 2709
2639 for (ActualParameter param : getModel().getParameters()) { 2710 for (ActualParameter param : getImplicitTypeParamters(getModel())) {
2640 if (!param.getSpecification().isSignature()) { 2711 clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), getContext().getType(Class.class), implicitTypeName(param)));
2641 continue; 2712 superConstructor.getParameters().add(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(param)));
2642 } 2713
2643 NodeChildData child = getModel().getNode().findChild(param.getSpecification().getName()); 2714 builder.startStatement();
2644 List<TypeData> types = child.getNodeData().getTypeSystem().lookupSourceTypes(param.getTypeSystemType()); 2715 builder.string("this.").string(implicitTypeName(param)).string(" = ").string(implicitTypeName(param));
2645 if (types.size() > 1) { 2716 builder.end();
2646 clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), getContext().getType(Class.class), implicitTypeName(param)));
2647 superConstructor.getParameters().add(new CodeVariableElement(getContext().getType(Class.class), implicitTypeName(param)));
2648
2649 builder.startStatement();
2650 builder.string("this.").string(implicitTypeName(param)).string(" = ").string(implicitTypeName(param));
2651 builder.end();
2652 }
2653 } 2717 }
2654 2718
2655 clazz.add(superConstructor); 2719 clazz.add(superConstructor);
2656 } 2720 }
2657 } 2721 }