Mercurial > hg > graal-jvmci-8
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 } |