Skip to content

Commit 81c43aa

Browse files
committed
Move isGeneratorFrame to PGenerator
1 parent e011038 commit 81c43aa

File tree

6 files changed

+72
-75
lines changed

6 files changed

+72
-75
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,32 @@
2727

2828
import com.oracle.graal.python.builtins.objects.frame.PFrame;
2929
import com.oracle.graal.python.builtins.objects.object.PythonObject;
30+
import com.oracle.graal.python.nodes.argument.CreateArgumentsNode;
3031
import com.oracle.graal.python.runtime.exception.PException;
3132
import com.oracle.truffle.api.exception.AbstractTruffleException;
3233
import com.oracle.truffle.api.frame.Frame;
3334

34-
//@formatter:off
3535
/**
3636
* The layout of an argument array for a Python frame.
37-
*
38-
* +-------------------+
39-
* SPECIAL_ARGUMENT -> | Object |
40-
* +-------------------+
41-
* INDEX_GLOBALS_ARGUMENT -> | PythonObject |
42-
* +-------------------+
43-
* INDEX_FUNCTION_OBJECT -> | PFunction |
44-
* +-------------------+
45-
* INDEX_CALLER_FRAME_INFO -> | PFrame.Reference |
46-
* +-------------------+
47-
* INDEX_CURRENT_FRAME_INFO -> | PFrame.Reference |
48-
* +-------------------+
49-
* INDEX_CURRENT_EXCEPTION -> | PException |
50-
* +-------------------+
51-
* USER_ARGUMENTS -> | arg_0 |
52-
* | arg_1 |
53-
* | ... |
54-
* | arg_(nArgs-1) |
55-
* +-------------------+
37+
* <ul>
38+
* <li>{@code SPECIAL_ARGUMENT (Object)}</li>
39+
* <li>{@code INDEX_GLOBALS_ARGUMENT (PythonObject)}</li>
40+
* <li>{@code INDEX_FUNCTION_OBJECT (PFunction)}</li>
41+
* <li>{@code INDEX_CALLER_FRAME_INFO (PFrame.Reference)}</li>
42+
* <li>{@code INDEX_CURRENT_FRAME_INFO (PFrame.Reference)}</li>
43+
* <li>{@code INDEX_CURRENT_EXCEPTION (PException)}</li>
44+
* <li>{@code USER_ARGUMENTS (Object...)}; Further defined by a particular call convention:
45+
* <ul>
46+
* <li>Function calls: non-variadic arguments as individual items in order of {@code co_varnames},
47+
* then varargs as {@code Object[]} iff the function takes them, then variadic keywords as
48+
* {@code PKeyword[]} iff the function takes them. Implemented by {@link CreateArgumentsNode}</li>
49+
* <li>Generator resumes (non-DSL): generator frame ({@code MaterializedFrame}), then the send value
50+
* or null</li>
51+
* <li>Generator resumes (DSL): doesn't use PArguments to call the continuation root</li>
52+
* </ul>
53+
* </li>
54+
* </ul>
5655
*/
57-
//@formatter:on
5856
public final class PArguments {
5957
private static final int INDEX_SPECIAL_ARGUMENT = 0;
6058
private static final int INDEX_GLOBALS_ARGUMENT = 1;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@
5959
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
6060
import com.oracle.graal.python.runtime.PythonOptions;
6161
import com.oracle.graal.python.runtime.object.PFactory;
62-
import com.oracle.graal.python.util.PythonUtils;
63-
import com.oracle.truffle.api.CompilerDirectives;
64-
import com.oracle.truffle.api.Truffle;
6562
import com.oracle.truffle.api.bytecode.BytecodeLocation;
6663
import com.oracle.truffle.api.bytecode.ContinuationResult;
6764
import com.oracle.truffle.api.dsl.Bind;
@@ -78,15 +75,6 @@
7875
@CoreFunctions(extendClasses = PythonBuiltinClassType.PGenerator)
7976
public final class GeneratorBuiltins extends PythonBuiltins {
8077

81-
private static void checkResumable(Node inliningTarget, PGenerator self, PRaiseNode raiseNode) {
82-
if (self.isFinished()) {
83-
throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.StopIteration);
84-
}
85-
if (self.isRunning()) {
86-
throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.GENERATOR_ALREADY_EXECUTING);
87-
}
88-
}
89-
9078
public static final TpSlots SLOTS = GeneratorBuiltinsSlotsGen.SLOTS;
9179

9280
@Override
@@ -195,36 +183,26 @@ static Object setRunning(@SuppressWarnings("unused") PGenerator self, @SuppressW
195183
@Builtin(name = "gi_frame", minNumOfPositionalArgs = 1, isGetter = true)
196184
@GenerateNodeFactory
197185
public abstract static class GetFrameNode extends PythonUnaryBuiltinNode {
198-
@CompilerDirectives.TruffleBoundary
199-
private static PFrame getBytecodeDSLMateriazedFrame(PGenerator self) {
200-
ContinuationResult continuation = self.getContinuation();
201-
if (continuation == null) {
202-
// TODO: GR-67147: implement properly, frame needs to be retrieved before
203-
// first use for coroutines
204-
Object[] args = new Object[self.getArguments().length];
205-
PythonUtils.arraycopy(self.getArguments(), 0, args, 0, self.getArguments().length);
206-
MaterializedFrame mframe = Truffle.getRuntime().createMaterializedFrame(args);
207-
PFrame frame = MaterializeFrameNode.materializeGeneratorFrame(null, mframe, PFrame.Reference.EMPTY);
208-
frame.setBci(0);
209-
return frame;
210-
}
211-
BytecodeLocation location = continuation.getBytecodeLocation();
212-
MaterializedFrame generatorFrame = continuation.getFrame();
213-
BytecodeDSLFrameInfo info = (BytecodeDSLFrameInfo) generatorFrame.getFrameDescriptor().getInfo();
214-
PFrame frame = MaterializeFrameNode.materializeGeneratorFrame(location.getBytecodeNode(), generatorFrame, PFrame.Reference.EMPTY);
215-
int bci = location.getBytecodeIndex();
216-
frame.setBci(bci);
217-
frame.setLine(info.getRootNode().bciToLine(bci, location.getBytecodeNode()));
218-
return frame;
219-
}
220186

221187
@Specialization
222188
static Object getFrame(PGenerator self) {
223189
if (self.isFinished()) {
224190
return PNone.NONE;
225191
} else {
226192
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
227-
return getBytecodeDSLMateriazedFrame(self);
193+
ContinuationResult continuation = self.getContinuation();
194+
BytecodeLocation location = continuation != null ? continuation.getBytecodeLocation() : null;
195+
MaterializedFrame generatorFrame = self.getGeneratorFrame();
196+
BytecodeDSLFrameInfo info = (BytecodeDSLFrameInfo) generatorFrame.getFrameDescriptor().getInfo();
197+
PFrame frame = MaterializeFrameNode.materializeGeneratorFrame(location != null ? location.getBytecodeNode() : null, generatorFrame, PFrame.Reference.EMPTY);
198+
if (location != null) {
199+
int bci = location.getBytecodeIndex();
200+
frame.setBci(bci);
201+
frame.setLine(info.getRootNode().bciToLine(bci, location.getBytecodeNode()));
202+
} else {
203+
frame.setBci(0);
204+
}
205+
return frame;
228206
} else {
229207
MaterializedFrame generatorFrame = self.getGeneratorFrame();
230208
BytecodeFrameInfo info = (BytecodeFrameInfo) generatorFrame.getFrameDescriptor().getInfo();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/PGenerator.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@
4242
import com.oracle.graal.python.nodes.bytecode_dsl.PBytecodeDSLRootNode;
4343
import com.oracle.graal.python.runtime.PythonOptions;
4444
import com.oracle.graal.python.runtime.object.PFactory;
45+
import com.oracle.graal.python.util.PythonUtils;
4546
import com.oracle.truffle.api.CompilerDirectives;
4647
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
48+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4749
import com.oracle.truffle.api.RootCallTarget;
50+
import com.oracle.truffle.api.Truffle;
4851
import com.oracle.truffle.api.bytecode.ContinuationResult;
4952
import com.oracle.truffle.api.frame.Frame;
5053
import com.oracle.truffle.api.frame.MaterializedFrame;
@@ -196,16 +199,47 @@ public Object[] getCallArguments(Object sendValue) {
196199
}
197200
}
198201

202+
public static boolean isGeneratorFrame(Frame frame) {
203+
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
204+
return false;
205+
}
206+
Object frameInfo = frame.getFrameDescriptor().getInfo();
207+
if (frameInfo instanceof BytecodeFrameInfo bytecodeFrameInfo) {
208+
return bytecodeFrameInfo.getCodeUnit().isGeneratorOrCoroutine();
209+
}
210+
return false;
211+
}
212+
199213
public static MaterializedFrame getGeneratorFrame(Object[] arguments) {
214+
assert !PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER;
200215
return (MaterializedFrame) PArguments.getArgument(arguments, 0);
201216
}
202217

203218
public static MaterializedFrame getGeneratorFrame(Frame frame) {
219+
assert isGeneratorFrame(frame);
204220
return getGeneratorFrame(frame.getArguments());
205221
}
206222

207223
public MaterializedFrame getGeneratorFrame() {
208-
return frame;
224+
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
225+
ContinuationResult continuation = getContinuation();
226+
if (continuation == null) {
227+
return fakeNonstartedFrame();
228+
}
229+
return continuation.getFrame();
230+
} else {
231+
return frame;
232+
}
233+
}
234+
235+
@TruffleBoundary
236+
private MaterializedFrame fakeNonstartedFrame() {
237+
// TODO: GR-67147: implement properly, frame needs to be retrieved before
238+
// first use for coroutines
239+
Object[] arguments = getBytecodeDSLState().arguments;
240+
Object[] args = new Object[arguments.length];
241+
PythonUtils.arraycopy(arguments, 0, args, 0, arguments.length);
242+
return Truffle.getRuntime().createMaterializedFrame(args);
209243
}
210244

211245
public static Object getSendValue(Object[] arguments) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,10 +3298,7 @@ private static Object doInvokeTraceFunction(PythonContext.TraceEvent event, PFra
32983298
}
32993299

33003300
private void syncLocalsBackToFrame(VirtualFrame virtualFrame, PFrame pyFrame, int bci) {
3301-
Frame localFrame = virtualFrame;
3302-
if (co.isGeneratorOrCoroutine()) {
3303-
localFrame = PArguments.getGeneratorFrame(virtualFrame);
3304-
}
3301+
Frame localFrame = getLocalFrame(virtualFrame);
33053302
if (pyFrame.localsAccessed()) {
33063303
enterTraceProfile(bci, TRACE_PROFILE_SYNC_LOCALS_BACK);
33073304
GetFrameLocalsNode.syncLocalsBackToFrame(co, this, pyFrame, localFrame);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/MaterializeFrameNode.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import com.oracle.truffle.api.dsl.GenerateInline;
6060
import com.oracle.truffle.api.dsl.GenerateUncached;
6161
import com.oracle.truffle.api.dsl.Idempotent;
62+
import com.oracle.truffle.api.dsl.ImportStatic;
6263
import com.oracle.truffle.api.dsl.NeverDefault;
6364
import com.oracle.truffle.api.dsl.ReportPolymorphism;
6465
import com.oracle.truffle.api.dsl.Specialization;
@@ -76,6 +77,7 @@
7677
@ReportPolymorphism
7778
@GenerateUncached
7879
@GenerateInline(false) // footprint reduction 36 -> 17
80+
@ImportStatic(PGenerator.class)
7981
public abstract class MaterializeFrameNode extends Node {
8082

8183
@NeverDefault
@@ -149,7 +151,7 @@ static PFrame alreadyEscapedFrame(@SuppressWarnings("unused") Node location, boo
149151
@Shared("syncValuesNode") @Cached SyncFrameValuesNode syncValuesNode,
150152
@Cached InlinedConditionProfile syncProfile) {
151153
PFrame pyFrame = getPFrame(frameToMaterialize);
152-
if (syncProfile.profile(inliningTarget, forceSync && !isGeneratorFrame(frameToMaterialize))) {
154+
if (syncProfile.profile(inliningTarget, forceSync && !PGenerator.isGeneratorFrame(frameToMaterialize))) {
153155
syncValuesNode.execute(pyFrame, frameToMaterialize);
154156
}
155157
if (markAsEscaped) {
@@ -211,17 +213,6 @@ private static PFrame doEscapeFrame(Frame frameToMaterialize, PFrame escapedFram
211213
return escapedFrame;
212214
}
213215

214-
protected static boolean isGeneratorFrame(Frame frame) {
215-
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
216-
return false;
217-
}
218-
Object frameInfo = frame.getFrameDescriptor().getInfo();
219-
if (frameInfo instanceof BytecodeFrameInfo bytecodeFrameInfo) {
220-
return bytecodeFrameInfo.getCodeUnit().isGeneratorOrCoroutine();
221-
}
222-
return false;
223-
}
224-
225216
protected static boolean hasCustomLocals(Frame frame) {
226217
return PArguments.getSpecialArgument(frame) != null;
227218
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/interop/PythonScopes.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@
4545
import com.oracle.graal.python.builtins.objects.function.PArguments;
4646
import com.oracle.graal.python.builtins.objects.generator.PGenerator;
4747
import com.oracle.graal.python.builtins.objects.object.PythonObject;
48-
import com.oracle.graal.python.nodes.bytecode.BytecodeFrameInfo;
4948
import com.oracle.truffle.api.TruffleLanguage;
5049
import com.oracle.truffle.api.dsl.Bind;
5150
import com.oracle.truffle.api.dsl.Cached;
@@ -94,7 +93,7 @@ public static Object create(Node node, Frame frame) {
9493
if (frame != null) {
9594
PythonObject globals = PArguments.getGlobalsSafe(frame);
9695
MaterializedFrame generatorFrame = null;
97-
if (frame.getFrameDescriptor().getInfo() instanceof BytecodeFrameInfo frameInfo && frameInfo.getCodeUnit().isGeneratorOrCoroutine()) {
96+
if (PGenerator.isGeneratorFrame(frame)) {
9897
generatorFrame = PGenerator.getGeneratorFrame(frame);
9998
}
10099
Object globalsScope = null;

0 commit comments

Comments
 (0)