comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java @ 11197:3479ab380552

Truffle-DSL: More elegant solution for rewrite with exception in executeAndSpecialize0.
author Christian Humer <christian.humer@gmail.com>
date Thu, 01 Aug 2013 21:34:57 +0200
parents 4f52b08bd2f9
children 7fc3e1fb3965
comparison
equal deleted inserted replaced
11196:498d0e531bbb 11197:3479ab380552
1427 builder.startStaticCall(getContext().getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end(); 1427 builder.startStaticCall(getContext().getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end();
1428 builder.end(); 1428 builder.end();
1429 1429
1430 emitSpecializationListeners(builder, node); 1430 emitSpecializationListeners(builder, node);
1431 1431
1432 String currentNode = "this";
1433 for (SpecializationData specialization : node.getSpecializations()) {
1434 if (!specialization.getExceptions().isEmpty()) {
1435 currentNode = "current";
1436 builder.declaration(baseClassName(node), currentNode, "this");
1437 break;
1438 }
1439 }
1440
1432 builder.startStatement().string("String message = ").startCall("createInfo0").string("reason"); 1441 builder.startStatement().string("String message = ").startCall("createInfo0").string("reason");
1433 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, false, true); 1442 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, false, true);
1434 builder.end().end(); 1443 builder.end().end();
1435 1444
1436 List<SpecializationData> specializations = node.getSpecializations(); 1445 List<SpecializationData> specializations = node.getSpecializations();
1442 filteredSpecializations.add(current); 1451 filteredSpecializations.add(current);
1443 } 1452 }
1444 1453
1445 List<SpecializationGroup> groups = SpecializationGroup.create(filteredSpecializations); 1454 List<SpecializationGroup> groups = SpecializationGroup.create(filteredSpecializations);
1446 1455
1456 final String currentNodeVar = currentNode;
1447 for (SpecializationGroup group : groups) { 1457 for (SpecializationGroup group : groups) {
1448 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, true, new CodeBlock<SpecializationData>() { 1458 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, true, new CodeBlock<SpecializationData>() {
1449 1459
1450 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { 1460 public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
1451 return createGenericInvokeAndSpecialize(b, node.getGenericSpecialization(), current); 1461 return createGenericInvokeAndSpecialize(b, node.getGenericSpecialization(), current, currentNodeVar);
1452 } 1462 }
1453 })); 1463 }));
1454 } 1464 }
1455 1465
1456 boolean firstUnreachable = true; 1466 boolean firstUnreachable = true;
1718 emitEncounteredSynthetic(builder, current); 1728 emitEncounteredSynthetic(builder, current);
1719 } else { 1729 } else {
1720 builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end(); 1730 builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end();
1721 } 1731 }
1722 1732
1723 return encloseThrowsWithFallThrough(current, builder.getRoot(), null); 1733 return encloseThrowsWithFallThrough(current, builder.getRoot());
1724 } 1734 }
1725 1735
1726 protected CodeTree createGenericInvokeAndSpecialize(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) { 1736 protected CodeTree createGenericInvokeAndSpecialize(CodeTreeBuilder parent, SpecializationData source, SpecializationData current, String currentNodeVar) {
1727 CodeTreeBuilder builder = parent.create(); 1737 CodeTreeBuilder builder = parent.create();
1728 CodeTreeBuilder prefix = parent.create(); 1738 CodeTreeBuilder prefix = parent.create();
1729 1739
1730 NodeData node = current.getNode(); 1740 NodeData node = current.getNode();
1731 1741
1732 String restoreNode = null;
1733 if (current.isGeneric() && node.isPolymorphic()) { 1742 if (current.isGeneric() && node.isPolymorphic()) {
1734 builder.startIf().string("next0 == null && minimumState > 0").end().startBlock(); 1743 builder.startIf().string(currentNodeVar).string(".next0 == null && minimumState > 0").end().startBlock();
1735 builder.tree(createRewritePolymorphic(builder, node)); 1744 builder.tree(createRewritePolymorphic(builder, node, currentNodeVar));
1736 builder.end(); 1745 builder.end();
1737 builder.startElseBlock(); 1746 builder.startElseBlock();
1738 builder.tree(createRewriteGeneric(builder, source, current)); 1747 builder.tree(createRewriteGeneric(builder, source, current, currentNodeVar));
1739 builder.end(); 1748 builder.end();
1740 } else { 1749 } else {
1741 // simple rewrite 1750 // simple rewrite
1742 if (current.getExceptions().isEmpty()) { 1751 if (current.getExceptions().isEmpty()) {
1743 builder.tree(createGenericInvoke(builder, source, current, createReplaceCall(builder, current, null, null))); 1752 builder.tree(createGenericInvoke(builder, source, current, createReplaceCall(builder, current, currentNodeVar, currentNodeVar, null)));
1744 } else { 1753 } else {
1745 prefix.declaration(baseClassName(node), "restoreNode", createReplaceCall(builder, current, null, null)); 1754 builder.startStatement().string(currentNodeVar).string(" = ").tree(createReplaceCall(builder, current, currentNodeVar, currentNodeVar, null)).end();
1746 builder.tree(createGenericInvoke(builder, source, current, CodeTreeBuilder.singleString("restoreNode"))); 1755 builder.tree(createGenericInvoke(builder, source, current, CodeTreeBuilder.singleString(currentNodeVar)));
1747 restoreNode = "restoreNode";
1748 } 1756 }
1749 } 1757 }
1750 CodeTreeBuilder root = parent.create(); 1758 CodeTreeBuilder root = parent.create();
1751 root.tree(prefix.getRoot()); 1759 root.tree(prefix.getRoot());
1752 root.tree(encloseThrowsWithFallThrough(current, builder.getRoot(), restoreNode)); 1760 root.tree(encloseThrowsWithFallThrough(current, builder.getRoot()));
1753 return root.getRoot(); 1761 return root.getRoot();
1754 } 1762 }
1755 1763
1756 private CodeTree createRewriteGeneric(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) { 1764 private CodeTree createRewriteGeneric(CodeTreeBuilder parent, SpecializationData source, SpecializationData current, String currentNode) {
1757 NodeData node = current.getNode(); 1765 NodeData node = current.getNode();
1758 1766
1759 CodeTreeBuilder builder = parent.create(); 1767 CodeTreeBuilder builder = parent.create();
1760 builder.declaration(getContext().getTruffleTypes().getNode(), "root", "this"); 1768 builder.declaration(getContext().getTruffleTypes().getNode(), "root", currentNode);
1761 builder.startIf().string("next0 != null").end().startBlock(); 1769 builder.startIf().string(currentNode).string(".next0 != null").end().startBlock();
1762 builder.tree(createFindRoot(builder, node, false)); 1770 builder.tree(createFindRoot(builder, node, false));
1763 builder.end(); 1771 builder.end();
1764 builder.end(); 1772 builder.end();
1765 builder.tree(createGenericInvoke(builder, source, current, createReplaceCall(builder, current, "root", null))); 1773 builder.tree(createGenericInvoke(builder, source, current, createReplaceCall(builder, current, "root", currentNode, null)));
1766 return builder.getRoot(); 1774 return builder.getRoot();
1767 } 1775 }
1768 1776
1769 protected CodeTree createFindRoot(CodeTreeBuilder parent, NodeData node, boolean countDepth) { 1777 protected CodeTree createFindRoot(CodeTreeBuilder parent, NodeData node, boolean countDepth) {
1770 CodeTreeBuilder builder = parent.create(); 1778 CodeTreeBuilder builder = parent.create();
1779 builder.string("!").startParantheses().instanceOf("root", nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization())).end(); 1787 builder.string("!").startParantheses().instanceOf("root", nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization())).end();
1780 builder.end(); 1788 builder.end();
1781 return builder.getRoot(); 1789 return builder.getRoot();
1782 } 1790 }
1783 1791
1784 private CodeTree encloseThrowsWithFallThrough(SpecializationData current, CodeTree tree, String restoreNodeVarName) { 1792 private CodeTree encloseThrowsWithFallThrough(SpecializationData current, CodeTree tree) {
1785 if (current.getExceptions().isEmpty()) { 1793 if (current.getExceptions().isEmpty()) {
1786 return tree; 1794 return tree;
1787 } 1795 }
1788 CodeTreeBuilder builder = new CodeTreeBuilder(null); 1796 CodeTreeBuilder builder = new CodeTreeBuilder(null);
1789 1797
1790 builder.startTryBlock(); 1798 builder.startTryBlock();
1791 builder.tree(tree); 1799 builder.tree(tree);
1792 for (SpecializationThrowsData exception : current.getExceptions()) { 1800 for (SpecializationThrowsData exception : current.getExceptions()) {
1793 builder.end().startCatchBlock(exception.getJavaClass(), "rewriteEx"); 1801 builder.end().startCatchBlock(exception.getJavaClass(), "rewriteEx");
1794 if (restoreNodeVarName != null) {
1795 builder.startStatement().startCall(restoreNodeVarName, "replace").string("this");
1796 builder.startGroup();
1797 builder.startCall("createInfo0").doubleQuote("Rewrite exception thrown " + Utils.getSimpleName(exception.getJavaClass()) + ".");
1798 addInternalValueParameterNames(builder, current, current, null, false, true);
1799 builder.end();
1800 builder.end();
1801 builder.end().end();
1802 }
1803
1804 builder.string("// fall through").newLine(); 1802 builder.string("// fall through").newLine();
1805 } 1803 }
1806 builder.end(); 1804 builder.end();
1807 1805
1808 return builder.getRoot(); 1806 return builder.getRoot();
1826 builder.startReturn().tree(createTemplateMethodCall(parent, replaceCall, source, current, null)).end(); 1824 builder.startReturn().tree(createTemplateMethodCall(parent, replaceCall, source, current, null)).end();
1827 } 1825 }
1828 return builder.getRoot(); 1826 return builder.getRoot();
1829 } 1827 }
1830 1828
1831 protected CodeTree createReplaceCall(CodeTreeBuilder builder, SpecializationData current, String target, String message) { 1829 protected CodeTree createReplaceCall(CodeTreeBuilder builder, SpecializationData current, String target, String source, String message) {
1832 String className = nodeSpecializationClassName(current); 1830 String className = nodeSpecializationClassName(current);
1833 CodeTreeBuilder replaceCall = builder.create(); 1831 CodeTreeBuilder replaceCall = builder.create();
1834 if (target != null) { 1832 if (target != null) {
1835 replaceCall.startCall(target, "replace"); 1833 replaceCall.startCall(target, "replace");
1836 } else { 1834 } else {
1837 replaceCall.startCall("replace"); 1835 replaceCall.startCall("replace");
1838 } 1836 }
1839 replaceCall.startGroup().startNew(className).string("this").end().end(); 1837 replaceCall.startGroup().startNew(className).string(source).end().end();
1840 if (message == null) { 1838 if (message == null) {
1841 replaceCall.string("message"); 1839 replaceCall.string("message");
1842 } else { 1840 } else {
1843 replaceCall.doubleQuote(message); 1841 replaceCall.doubleQuote(message);
1844 } 1842 }
1845 replaceCall.end(); 1843 replaceCall.end();
1846 return replaceCall.getRoot(); 1844 return replaceCall.getRoot();
1847 } 1845 }
1848 1846
1849 private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node) { 1847 private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) {
1850 String polyClassName = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization()); 1848 String polyClassName = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization());
1851 String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization()); 1849 String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization());
1852 CodeTreeBuilder builder = parent.create(); 1850 CodeTreeBuilder builder = parent.create();
1853 1851
1854 builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string("this").end()); 1852 builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string(currentNode).end());
1855 1853
1856 for (ActualParameter param : node.getGenericSpecialization().getParameters()) { 1854 for (ActualParameter param : node.getGenericSpecialization().getParameters()) {
1857 if (!param.getSpecification().isSignature()) { 1855 if (!param.getSpecification().isSignature()) {
1858 continue; 1856 continue;
1859 } 1857 }
1860 NodeChildData child = node.findChild(param.getSpecification().getName()); 1858 NodeChildData child = node.findChild(param.getSpecification().getName());
1861 if (child != null) { 1859 if (child != null) {
1862 builder.startStatement().string("this.").string(child.getName()); 1860 builder.startStatement().string(currentNode).string(".").string(child.getName());
1863 if (child.getCardinality().isMany()) { 1861 if (child.getCardinality().isMany()) {
1864 builder.string("[").string(String.valueOf(param.getIndex())).string("]"); 1862 builder.string("[").string(String.valueOf(param.getIndex())).string("]");
1865 } 1863 }
1866 builder.string(" = null").end(); 1864 builder.string(" = null").end();
1867 } 1865 }
1868 } 1866 }
1869 builder.startStatement().startCall("super", "replace").string("polymorphic").string("message").end().end(); 1867 builder.startStatement().startCall(currentNode, "replace").string("polymorphic").string("message").end().end();
1870 builder.startStatement().startCall("polymorphic", "setNext0").string("this").end().end(); 1868 builder.startStatement().startCall("polymorphic", "setNext0").string(currentNode).end().end();
1871 builder.startStatement().startCall("setNext0").startNew(uninitializedName).string("this").end().end().end(); 1869 builder.startStatement().startCall(currentNode, "setNext0").startNew(uninitializedName).string(currentNode).end().end().end();
1872 1870
1873 builder.startReturn(); 1871 builder.startReturn();
1874 builder.startCall("next0", executeCachedName(node.getGenericPolymorphicSpecialization())); 1872 builder.startCall(currentNode + ".next0", executeCachedName(node.getGenericPolymorphicSpecialization()));
1875 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, true); 1873 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, true);
1876 builder.end(); 1874 builder.end();
1877 builder.end(); 1875 builder.end();
1878 1876
1879 return builder.getRoot(); 1877 return builder.getRoot();
2494 2492
2495 builder.startIf().string("depth > ").string(String.valueOf(node.getPolymorphicDepth())).end(); 2493 builder.startIf().string("depth > ").string(String.valueOf(node.getPolymorphicDepth())).end();
2496 builder.startBlock(); 2494 builder.startBlock();
2497 String message = ("Polymorphic limit reached (" + node.getPolymorphicDepth() + ")"); 2495 String message = ("Polymorphic limit reached (" + node.getPolymorphicDepth() + ")");
2498 builder.tree(createGenericInvoke(builder, node.getGenericPolymorphicSpecialization(), node.getGenericSpecialization(), 2496 builder.tree(createGenericInvoke(builder, node.getGenericPolymorphicSpecialization(), node.getGenericSpecialization(),
2499 createReplaceCall(builder, node.getGenericSpecialization(), "root", message))); 2497 createReplaceCall(builder, node.getGenericSpecialization(), "root", "this", message)));
2500 builder.end(); 2498 builder.end();
2501 2499
2502 builder.startElseBlock(); 2500 builder.startElseBlock();
2503 builder.startStatement().startCall("setNext0"); 2501 builder.startStatement().startCall("setNext0");
2504 builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end(); 2502 builder.startNew(nodeSpecializationClassName(node.getUninitializedSpecialization())).string("this").end();