changeset 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 498d0e531bbb
children 1e6d5dec4a4e
files graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java
diffstat 1 files changed, 35 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Thu Aug 01 20:54:32 2013 +0200
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Thu Aug 01 21:34:57 2013 +0200
@@ -1429,6 +1429,15 @@
 
             emitSpecializationListeners(builder, node);
 
+            String currentNode = "this";
+            for (SpecializationData specialization : node.getSpecializations()) {
+                if (!specialization.getExceptions().isEmpty()) {
+                    currentNode = "current";
+                    builder.declaration(baseClassName(node), currentNode, "this");
+                    break;
+                }
+            }
+
             builder.startStatement().string("String message = ").startCall("createInfo0").string("reason");
             addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, false, true);
             builder.end().end();
@@ -1444,11 +1453,12 @@
 
             List<SpecializationGroup> groups = SpecializationGroup.create(filteredSpecializations);
 
+            final String currentNodeVar = currentNode;
             for (SpecializationGroup group : groups) {
                 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, true, new CodeBlock<SpecializationData>() {
 
                     public CodeTree create(CodeTreeBuilder b, SpecializationData current) {
-                        return createGenericInvokeAndSpecialize(b, node.getGenericSpecialization(), current);
+                        return createGenericInvokeAndSpecialize(b, node.getGenericSpecialization(), current, currentNodeVar);
                     }
                 }));
             }
@@ -1720,49 +1730,47 @@
                 builder.startReturn().tree(createTemplateMethodCall(builder, null, source, current, null)).end();
             }
 
-            return encloseThrowsWithFallThrough(current, builder.getRoot(), null);
+            return encloseThrowsWithFallThrough(current, builder.getRoot());
         }
 
-        protected CodeTree createGenericInvokeAndSpecialize(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) {
+        protected CodeTree createGenericInvokeAndSpecialize(CodeTreeBuilder parent, SpecializationData source, SpecializationData current, String currentNodeVar) {
             CodeTreeBuilder builder = parent.create();
             CodeTreeBuilder prefix = parent.create();
 
             NodeData node = current.getNode();
 
-            String restoreNode = null;
             if (current.isGeneric() && node.isPolymorphic()) {
-                builder.startIf().string("next0 == null && minimumState > 0").end().startBlock();
-                builder.tree(createRewritePolymorphic(builder, node));
+                builder.startIf().string(currentNodeVar).string(".next0 == null && minimumState > 0").end().startBlock();
+                builder.tree(createRewritePolymorphic(builder, node, currentNodeVar));
                 builder.end();
                 builder.startElseBlock();
-                builder.tree(createRewriteGeneric(builder, source, current));
+                builder.tree(createRewriteGeneric(builder, source, current, currentNodeVar));
                 builder.end();
             } else {
                 // simple rewrite
                 if (current.getExceptions().isEmpty()) {
-                    builder.tree(createGenericInvoke(builder, source, current, createReplaceCall(builder, current, null, null)));
+                    builder.tree(createGenericInvoke(builder, source, current, createReplaceCall(builder, current, currentNodeVar, currentNodeVar, null)));
                 } else {
-                    prefix.declaration(baseClassName(node), "restoreNode", createReplaceCall(builder, current, null, null));
-                    builder.tree(createGenericInvoke(builder, source, current, CodeTreeBuilder.singleString("restoreNode")));
-                    restoreNode = "restoreNode";
+                    builder.startStatement().string(currentNodeVar).string(" = ").tree(createReplaceCall(builder, current, currentNodeVar, currentNodeVar, null)).end();
+                    builder.tree(createGenericInvoke(builder, source, current, CodeTreeBuilder.singleString(currentNodeVar)));
                 }
             }
             CodeTreeBuilder root = parent.create();
             root.tree(prefix.getRoot());
-            root.tree(encloseThrowsWithFallThrough(current, builder.getRoot(), restoreNode));
+            root.tree(encloseThrowsWithFallThrough(current, builder.getRoot()));
             return root.getRoot();
         }
 
-        private CodeTree createRewriteGeneric(CodeTreeBuilder parent, SpecializationData source, SpecializationData current) {
+        private CodeTree createRewriteGeneric(CodeTreeBuilder parent, SpecializationData source, SpecializationData current, String currentNode) {
             NodeData node = current.getNode();
 
             CodeTreeBuilder builder = parent.create();
-            builder.declaration(getContext().getTruffleTypes().getNode(), "root", "this");
-            builder.startIf().string("next0 != null").end().startBlock();
+            builder.declaration(getContext().getTruffleTypes().getNode(), "root", currentNode);
+            builder.startIf().string(currentNode).string(".next0 != null").end().startBlock();
             builder.tree(createFindRoot(builder, node, false));
             builder.end();
             builder.end();
-            builder.tree(createGenericInvoke(builder, source, current, createReplaceCall(builder, current, "root", null)));
+            builder.tree(createGenericInvoke(builder, source, current, createReplaceCall(builder, current, "root", currentNode, null)));
             return builder.getRoot();
         }
 
@@ -1781,7 +1789,7 @@
             return builder.getRoot();
         }
 
-        private CodeTree encloseThrowsWithFallThrough(SpecializationData current, CodeTree tree, String restoreNodeVarName) {
+        private CodeTree encloseThrowsWithFallThrough(SpecializationData current, CodeTree tree) {
             if (current.getExceptions().isEmpty()) {
                 return tree;
             }
@@ -1791,16 +1799,6 @@
             builder.tree(tree);
             for (SpecializationThrowsData exception : current.getExceptions()) {
                 builder.end().startCatchBlock(exception.getJavaClass(), "rewriteEx");
-                if (restoreNodeVarName != null) {
-                    builder.startStatement().startCall(restoreNodeVarName, "replace").string("this");
-                    builder.startGroup();
-                    builder.startCall("createInfo0").doubleQuote("Rewrite exception thrown " + Utils.getSimpleName(exception.getJavaClass()) + ".");
-                    addInternalValueParameterNames(builder, current, current, null, false, true);
-                    builder.end();
-                    builder.end();
-                    builder.end().end();
-                }
-
                 builder.string("// fall through").newLine();
             }
             builder.end();
@@ -1828,7 +1826,7 @@
             return builder.getRoot();
         }
 
-        protected CodeTree createReplaceCall(CodeTreeBuilder builder, SpecializationData current, String target, String message) {
+        protected CodeTree createReplaceCall(CodeTreeBuilder builder, SpecializationData current, String target, String source, String message) {
             String className = nodeSpecializationClassName(current);
             CodeTreeBuilder replaceCall = builder.create();
             if (target != null) {
@@ -1836,7 +1834,7 @@
             } else {
                 replaceCall.startCall("replace");
             }
-            replaceCall.startGroup().startNew(className).string("this").end().end();
+            replaceCall.startGroup().startNew(className).string(source).end().end();
             if (message == null) {
                 replaceCall.string("message");
             } else {
@@ -1846,12 +1844,12 @@
             return replaceCall.getRoot();
         }
 
-        private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node) {
+        private CodeTree createRewritePolymorphic(CodeTreeBuilder parent, NodeData node, String currentNode) {
             String polyClassName = nodePolymorphicClassName(node, node.getGenericPolymorphicSpecialization());
             String uninitializedName = nodeSpecializationClassName(node.getUninitializedSpecialization());
             CodeTreeBuilder builder = parent.create();
 
-            builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string("this").end());
+            builder.declaration(polyClassName, "polymorphic", builder.create().startNew(polyClassName).string(currentNode).end());
 
             for (ActualParameter param : node.getGenericSpecialization().getParameters()) {
                 if (!param.getSpecification().isSignature()) {
@@ -1859,19 +1857,19 @@
                 }
                 NodeChildData child = node.findChild(param.getSpecification().getName());
                 if (child != null) {
-                    builder.startStatement().string("this.").string(child.getName());
+                    builder.startStatement().string(currentNode).string(".").string(child.getName());
                     if (child.getCardinality().isMany()) {
                         builder.string("[").string(String.valueOf(param.getIndex())).string("]");
                     }
                     builder.string(" = null").end();
                 }
             }
-            builder.startStatement().startCall("super", "replace").string("polymorphic").string("message").end().end();
-            builder.startStatement().startCall("polymorphic", "setNext0").string("this").end().end();
-            builder.startStatement().startCall("setNext0").startNew(uninitializedName).string("this").end().end().end();
+            builder.startStatement().startCall(currentNode, "replace").string("polymorphic").string("message").end().end();
+            builder.startStatement().startCall("polymorphic", "setNext0").string(currentNode).end().end();
+            builder.startStatement().startCall(currentNode, "setNext0").startNew(uninitializedName).string(currentNode).end().end().end();
 
             builder.startReturn();
-            builder.startCall("next0", executeCachedName(node.getGenericPolymorphicSpecialization()));
+            builder.startCall(currentNode + ".next0", executeCachedName(node.getGenericPolymorphicSpecialization()));
             addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, true);
             builder.end();
             builder.end();
@@ -2496,7 +2494,7 @@
             builder.startBlock();
             String message = ("Polymorphic limit reached (" + node.getPolymorphicDepth() + ")");
             builder.tree(createGenericInvoke(builder, node.getGenericPolymorphicSpecialization(), node.getGenericSpecialization(),
-                            createReplaceCall(builder, node.getGenericSpecialization(), "root", message)));
+                            createReplaceCall(builder, node.getGenericSpecialization(), "root", "this", message)));
             builder.end();
 
             builder.startElseBlock();