Mercurial > hg > graal-compiler
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(); |