34
34
import com .oracle .graal .python .builtins .objects .function .PArguments ;
35
35
import com .oracle .graal .python .builtins .objects .iterator .PIntRangeIterator ;
36
36
import com .oracle .graal .python .builtins .objects .object .PythonBuiltinObject ;
37
+ import com .oracle .graal .python .nodes .bytecode .PBytecodeGeneratorRootNode ;
37
38
import com .oracle .graal .python .nodes .bytecode .PBytecodeRootNode ;
38
39
import com .oracle .graal .python .nodes .generator .AbstractYieldNode ;
39
40
import com .oracle .graal .python .nodes .generator .YieldFromNode ;
42
43
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
43
44
import com .oracle .truffle .api .Assumption ;
44
45
import com .oracle .truffle .api .CompilerAsserts ;
46
+ import com .oracle .truffle .api .CompilerDirectives ;
45
47
import com .oracle .truffle .api .CompilerDirectives .CompilationFinal ;
46
48
import com .oracle .truffle .api .RootCallTarget ;
47
49
import com .oracle .truffle .api .Truffle ;
@@ -54,7 +56,6 @@ public final class PGenerator extends PythonBuiltinObject {
54
56
55
57
private String name ;
56
58
private String qualname ;
57
- private final boolean usesBytecode ;
58
59
/**
59
60
* Call targets with copies of the generator's AST. Each call target corresponds to one possible
60
61
* entry point into the generator: the first call, and continuation for each yield. Each AST can
@@ -71,6 +72,8 @@ public final class PGenerator extends PythonBuiltinObject {
71
72
private final Object iterator ;
72
73
private final boolean isPRangeIterator ;
73
74
private final GeneratorInfo generatorInfo ;
75
+ private final PBytecodeRootNode bytecodeRootNode ;
76
+ private final PBytecodeRootNode .FrameInfo frameInfo ;
74
77
// running means it is currently on the stack, not just started
75
78
private boolean running ;
76
79
@@ -106,12 +109,12 @@ public static PGenerator create(PythonLanguage lang, String name, String qualnam
106
109
}
107
110
assignCells (generatorFrame , cellVarSlots , cellVarAssumptions );
108
111
PArguments .setGeneratorFrameLocals (generatorFrameArguments , factory .createDictLocals (generatorFrame ));
109
- return new PGenerator (lang , name , qualname , callTargets , generatorInfo , arguments , closure , iterator , false );
112
+ return new PGenerator (lang , name , qualname , callTargets , generatorInfo , arguments , closure , iterator );
110
113
}
111
114
112
- public static PGenerator create (PythonLanguage lang , String name , String qualname , PBytecodeRootNode rootNode , RootCallTarget bytecodeCallTarget , Object [] arguments ) {
115
+ public static PGenerator create (PythonLanguage lang , String name , String qualname , PBytecodeRootNode rootNode , RootCallTarget [] callTargets , Object [] arguments ) {
113
116
rootNode .createGeneratorFrame (arguments );
114
- return new PGenerator (lang , name , qualname , new RootCallTarget []{ bytecodeCallTarget }, null , arguments , null , null , true );
117
+ return new PGenerator (lang , name , qualname , rootNode , callTargets , arguments );
115
118
}
116
119
117
120
@ ExplodeLoop
@@ -131,7 +134,7 @@ private static void assignClosure(PCell[] closure, MaterializedFrame generatorFr
131
134
}
132
135
133
136
private PGenerator (PythonLanguage lang , String name , String qualname , RootCallTarget [] callTargets , GeneratorInfo generatorInfo , Object [] arguments ,
134
- PCell [] closure , Object iterator , boolean usesBytecode ) {
137
+ PCell [] closure , Object iterator ) {
135
138
super (PythonBuiltinClassType .PGenerator , PythonBuiltinClassType .PGenerator .getInstanceShape (lang ));
136
139
this .name = name ;
137
140
this .qualname = qualname ;
@@ -143,11 +146,35 @@ private PGenerator(PythonLanguage lang, String name, String qualname, RootCallTa
143
146
this .finished = false ;
144
147
this .iterator = iterator ;
145
148
this .isPRangeIterator = iterator instanceof PIntRangeIterator ;
146
- this .usesBytecode = usesBytecode ;
149
+ this .bytecodeRootNode = null ;
150
+ this .frameInfo = null ;
147
151
}
148
152
149
- public void setNextCallTarget () {
150
- if (!usesBytecode ) {
153
+ private PGenerator (PythonLanguage lang , String name , String qualname , PBytecodeRootNode rootNode , RootCallTarget [] callTargets , Object [] arguments ) {
154
+ super (PythonBuiltinClassType .PGenerator , PythonBuiltinClassType .PGenerator .getInstanceShape (lang ));
155
+ this .name = name ;
156
+ this .qualname = qualname ;
157
+ this .callTargets = callTargets ;
158
+ this .currentCallTarget = 0 ;
159
+ this .arguments = arguments ;
160
+ this .finished = false ;
161
+ this .bytecodeRootNode = rootNode ;
162
+ this .frameInfo = (PBytecodeRootNode .FrameInfo ) rootNode .getFrameDescriptor ().getInfo ();
163
+ this .iterator = null ;
164
+ this .isPRangeIterator = false ;
165
+ this .closure = null ;
166
+ this .generatorInfo = null ;
167
+ }
168
+
169
+ public void setNextCallTarget (PythonLanguage language ) {
170
+ if (usesBytecode ()) {
171
+ currentCallTarget = getBci ();
172
+ if (callTargets [currentCallTarget ] == null ) {
173
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
174
+ PBytecodeGeneratorRootNode rootNode = new PBytecodeGeneratorRootNode (language , bytecodeRootNode , currentCallTarget , getStackTop ());
175
+ callTargets [currentCallTarget ] = rootNode .getCallTarget ();
176
+ }
177
+ } else {
151
178
currentCallTarget = PArguments .getControlDataFromGeneratorArguments (getArguments ()).getLastYieldIndex ();
152
179
}
153
180
}
@@ -162,6 +189,7 @@ public RootCallTarget getCurrentCallTarget() {
162
189
}
163
190
164
191
public AbstractYieldNode getCurrentYieldNode () {
192
+ assert !usesBytecode ();
165
193
if (currentCallTarget == 0 || running || finished ) {
166
194
// Not stopped on a yield
167
195
return null ;
@@ -171,38 +199,36 @@ public AbstractYieldNode getCurrentYieldNode() {
171
199
}
172
200
173
201
public boolean usesBytecode () {
174
- return usesBytecode ;
202
+ return bytecodeRootNode != null ;
175
203
}
176
204
177
205
public Object getYieldFrom () {
178
- if (!usesBytecode ) {
206
+ if (!usesBytecode () ) {
179
207
AbstractYieldNode currentYield = getCurrentYieldNode ();
180
208
if (currentYield instanceof YieldFromNode ) {
181
209
int iteratorSlot = ((YieldFromNode ) currentYield ).getIteratorSlot ();
182
210
return PArguments .getControlDataFromGeneratorArguments (arguments ).getIteratorAt (iteratorSlot );
183
211
}
184
212
return null ;
185
213
} else {
186
- MaterializedFrame generatorFrame = PArguments .getGeneratorFrame (arguments );
187
- PBytecodeRootNode .FrameInfo info = (PBytecodeRootNode .FrameInfo ) generatorFrame .getFrameDescriptor ().getInfo ();
188
- return info .getYieldFrom (generatorFrame );
214
+ return frameInfo .getYieldFrom (PArguments .getGeneratorFrame (arguments ));
189
215
}
190
216
}
191
217
192
218
public boolean isStarted () {
193
- return ( currentCallTarget != 0 || usesBytecode && getBci () > 0 ) && !running ;
219
+ return currentCallTarget != 0 && !running ;
194
220
}
195
221
196
222
public int getBci () {
197
- MaterializedFrame generatorFrame = PArguments .getGeneratorFrame (arguments );
198
- PBytecodeRootNode .FrameInfo info = (PBytecodeRootNode .FrameInfo ) generatorFrame .getFrameDescriptor ().getInfo ();
199
- return info .getBci (generatorFrame );
223
+ return frameInfo .getBci (PArguments .getGeneratorFrame (arguments ));
224
+ }
225
+
226
+ public int getStackTop () {
227
+ return frameInfo .getGeneratorStackTop (PArguments .getGeneratorFrame (arguments ));
200
228
}
201
229
202
230
public Object getReturnValue () {
203
- MaterializedFrame generatorFrame = PArguments .getGeneratorFrame (arguments );
204
- PBytecodeRootNode .FrameInfo info = (PBytecodeRootNode .FrameInfo ) generatorFrame .getFrameDescriptor ().getInfo ();
205
- return info .getGeneratorReturnValue (generatorFrame );
231
+ return frameInfo .getGeneratorReturnValue (PArguments .getGeneratorFrame (arguments ));
206
232
}
207
233
208
234
public Object [] getArguments () {
0 commit comments