46
46
import com .oracle .truffle .api .frame .VirtualFrame ;
47
47
import com .oracle .truffle .api .nodes .ExplodeLoop ;
48
48
import com .oracle .truffle .api .nodes .NodeUtil ;
49
+ import com .oracle .truffle .api .nodes .NodeVisitor ;
50
+ import com .oracle .truffle .api .nodes .RootNode ;
49
51
import com .oracle .truffle .api .profiles .BranchProfile ;
50
52
import com .oracle .truffle .api .profiles .ConditionProfile ;
51
53
import com .oracle .truffle .api .profiles .ValueProfile ;
@@ -67,26 +69,60 @@ public class FunctionRootNode extends PClosureFunctionRootNode {
67
69
@ Child private ExpressionNode body ;
68
70
@ Child private CalleeContext calleeContext = CalleeContext .create ();
69
71
70
- private ExpressionNode uninitializedBody ;
71
- private boolean isRewritten = false ;
72
+ private final ExpressionNode uninitializedBody ;
73
+ private final boolean isRewritten ;
72
74
73
- public FunctionRootNode (PythonLanguage language , SourceSection sourceSection , String functionName , boolean isGenerator , boolean isRewritten , FrameDescriptor frameDescriptor , ExpressionNode body ,
74
- ExecutionCellSlots executionCellSlots , Signature signature ) {
75
+ public FunctionRootNode (PythonLanguage language , SourceSection sourceSection , String functionName , boolean isGenerator , boolean isRewritten , FrameDescriptor frameDescriptor ,
76
+ ExpressionNode uninitializedBody , ExecutionCellSlots executionCellSlots , Signature signature ) {
75
77
super (language , frameDescriptor , executionCellSlots , signature );
76
78
this .executionCellSlots = executionCellSlots ;
77
79
78
80
this .sourceSection = sourceSection ;
79
81
assert sourceSection != null ;
80
82
this .functionName = functionName ;
81
83
this .isGenerator = isGenerator ;
82
- this .body = new InnerRootNode (this , NodeUtil .cloneNode (body ));
83
- this .uninitializedBody = NodeUtil .cloneNode (body );
84
+ this .body = new InnerRootNode (this , NodeUtil .cloneNode (uninitializedBody ));
85
+ // "uninitializedBody" is never modified or executed
86
+ this .uninitializedBody = uninitializedBody ;
84
87
this .generatorFrameProfile = isGenerator ? ValueProfile .createClassProfile () : null ;
85
88
this .isRewritten = isRewritten ;
86
89
}
87
90
88
- public FunctionRootNode copyWithNewSignature (Signature newSignature ) {
89
- return new FunctionRootNode (PythonLanguage .getCurrent (), getSourceSection (), functionName , isGenerator , isRewritten , getFrameDescriptor (), uninitializedBody , executionCellSlots , newSignature );
91
+ /**
92
+ * Creates a shallow copy.
93
+ */
94
+ private FunctionRootNode (FunctionRootNode other ) {
95
+ super (PythonLanguage .getCurrent (), other .getFrameDescriptor (), other .executionCellSlots , other .getSignature ());
96
+ this .executionCellSlots = other .executionCellSlots ;
97
+
98
+ this .sourceSection = other .getSourceSection ();
99
+ this .functionName = other .functionName ;
100
+ this .isGenerator = other .isGenerator ;
101
+ this .generatorFrameProfile = other .isGenerator ? ValueProfile .createClassProfile () : null ;
102
+ this .isRewritten = other .isRewritten ;
103
+ this .uninitializedBody = other .uninitializedBody ;
104
+ }
105
+
106
+ @ Override
107
+ protected boolean isCloneUninitializedSupported () {
108
+ return true ;
109
+ }
110
+
111
+ @ Override
112
+ protected RootNode cloneUninitialized () {
113
+ return new FunctionRootNode (PythonLanguage .getCurrent (), getSourceSection (), functionName , isGenerator , isRewritten , getFrameDescriptor (), uninitializedBody , executionCellSlots ,
114
+ getSignature ());
115
+ }
116
+
117
+ /**
118
+ * Returns a new function that has its signature replaced and whose body has been modified by
119
+ * the given node visitor.
120
+ */
121
+ public FunctionRootNode rewriteWithNewSignature (Signature newSignature , NodeVisitor nodeVisitor ) {
122
+ ExpressionNode newUninitializedBody = NodeUtil .cloneNode (uninitializedBody );
123
+ newUninitializedBody .accept (nodeVisitor );
124
+ return new FunctionRootNode (PythonLanguage .getCurrent (), getSourceSection (), functionName , isGenerator , true , getFrameDescriptor (), newUninitializedBody , executionCellSlots ,
125
+ newSignature );
90
126
}
91
127
92
128
public boolean isLambda () {
@@ -104,8 +140,7 @@ public FrameSlot[] getCellVarSlots() {
104
140
105
141
@ Override
106
142
public FunctionRootNode copy () {
107
- return new FunctionRootNode (PythonLanguage .getCurrent (), getSourceSection (), functionName , isGenerator , isRewritten , getFrameDescriptor (), uninitializedBody ,
108
- executionCellSlots , getSignature ());
143
+ return new FunctionRootNode (this );
109
144
}
110
145
111
146
@ ExplodeLoop
@@ -175,13 +210,6 @@ public boolean isRewritten() {
175
210
return isRewritten ;
176
211
}
177
212
178
- public void setRewritten () {
179
- this .isRewritten = true ;
180
-
181
- // we need to update the uninitialized body as well
182
- this .uninitializedBody = NodeUtil .cloneNode (body );
183
- }
184
-
185
213
@ Override
186
214
public void initializeFrame (VirtualFrame frame ) {
187
215
initClosureAndCellVars (frame );
0 commit comments