Skip to content

Commit e011038

Browse files
committed
Remove generator frame from fixed PArguments slots
1 parent 01b4cb3 commit e011038

File tree

13 files changed

+143
-166
lines changed

13 files changed

+143
-166
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/asyncio/PAsyncGen.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,24 @@
4242

4343
import com.oracle.graal.python.PythonLanguage;
4444
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
45+
import com.oracle.graal.python.builtins.objects.function.PFunction;
4546
import com.oracle.graal.python.builtins.objects.generator.PGenerator;
4647
import com.oracle.graal.python.nodes.bytecode.PBytecodeRootNode;
4748
import com.oracle.truffle.api.RootCallTarget;
48-
import com.oracle.truffle.api.strings.TruffleString;
49+
import com.oracle.truffle.api.frame.MaterializedFrame;
4950

5051
public final class PAsyncGen extends PGenerator {
5152
private boolean closed = false;
5253
private boolean hookCalled = false;
5354
private boolean runningAsync = false;
5455

55-
public static PAsyncGen create(PythonLanguage lang, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) {
56-
rootNode.createGeneratorFrame(arguments);
57-
return new PAsyncGen(lang, name, qualname, rootNode, callTargets, arguments);
56+
public static PAsyncGen create(PythonLanguage lang, PFunction function, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) {
57+
MaterializedFrame generatorFrame = rootNode.createGeneratorFrame(arguments);
58+
return new PAsyncGen(lang, function, generatorFrame, rootNode, callTargets, arguments);
5859
}
5960

60-
private PAsyncGen(PythonLanguage lang, TruffleString name, TruffleString qualname, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) {
61-
super(lang, name, qualname, arguments, PythonBuiltinClassType.PAsyncGenerator, false, new BytecodeState(rootNode, callTargets));
61+
private PAsyncGen(PythonLanguage lang, PFunction function, MaterializedFrame generatorFrame, PBytecodeRootNode rootNode, RootCallTarget[] callTargets, Object[] arguments) {
62+
super(lang, function, generatorFrame, PythonBuiltinClassType.PAsyncGenerator, false, new BytecodeState(rootNode, callTargets));
6263
}
6364

6465
public boolean isClosed() {

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

Lines changed: 7 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,15 @@
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.runtime.PythonOptions;
3130
import com.oracle.graal.python.runtime.exception.PException;
3231
import com.oracle.truffle.api.exception.AbstractTruffleException;
3332
import com.oracle.truffle.api.frame.Frame;
34-
import com.oracle.truffle.api.frame.MaterializedFrame;
3533

3634
//@formatter:off
3735
/**
3836
* The layout of an argument array for a Python frame.
3937
*
4038
* +-------------------+
41-
* INDEX_GENERATOR_FRAME -> | MaterializedFrame |
42-
* +-------------------+
4339
* SPECIAL_ARGUMENT -> | Object |
4440
* +-------------------+
4541
* INDEX_GLOBALS_ARGUMENT -> | PythonObject |
@@ -60,14 +56,13 @@
6056
*/
6157
//@formatter:on
6258
public final class PArguments {
63-
private static final int INDEX_GENERATOR_FRAME = 0;
64-
private static final int INDEX_SPECIAL_ARGUMENT = 1;
65-
private static final int INDEX_GLOBALS_ARGUMENT = 2;
66-
private static final int INDEX_FUNCTION_OBJECT = 3;
67-
private static final int INDEX_CALLER_FRAME_INFO = 4;
68-
private static final int INDEX_CURRENT_FRAME_INFO = 5;
69-
private static final int INDEX_CURRENT_EXCEPTION = 6;
70-
public static final int USER_ARGUMENTS_OFFSET = 7;
59+
private static final int INDEX_SPECIAL_ARGUMENT = 0;
60+
private static final int INDEX_GLOBALS_ARGUMENT = 1;
61+
private static final int INDEX_FUNCTION_OBJECT = 2;
62+
private static final int INDEX_CALLER_FRAME_INFO = 3;
63+
private static final int INDEX_CURRENT_FRAME_INFO = 4;
64+
private static final int INDEX_CURRENT_EXCEPTION = 5;
65+
public static final int USER_ARGUMENTS_OFFSET = 6;
7166

7267
public static boolean isPythonFrame(Frame frame) {
7368
return frame != null && isPythonFrame(frame.getArguments());
@@ -104,8 +99,6 @@ public static void setSpecialArgument(Object[] arguments, Object value) {
10499
/**
105100
* The special argument is used for various purposes, none of which can occur at the same time:
106101
* <ul>
107-
* <li>The value sent to a generator via <code>send</code></li>
108-
* <li>An exception thrown through a generator via <code>throw</code></li>
109102
* <li>The custom locals in a module or class scope when called through <code>exec</code> or
110103
* <code>__build_class__</code></li>
111104
* </ul>
@@ -218,31 +211,6 @@ public static Object getArgument(Frame frame, int index) {
218211
return getArgument(frame.getArguments(), index);
219212
}
220213

221-
public static MaterializedFrame getGeneratorFrame(Object[] arguments) {
222-
assert !PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER;
223-
return (MaterializedFrame) arguments[INDEX_GENERATOR_FRAME];
224-
}
225-
226-
public static MaterializedFrame getGeneratorFrame(Frame frame) {
227-
return getGeneratorFrame(frame.getArguments());
228-
}
229-
230-
public static MaterializedFrame getGeneratorFrameSafe(Frame frame) {
231-
return getGeneratorFrameSafe(frame.getArguments());
232-
}
233-
234-
public static MaterializedFrame getGeneratorFrameSafe(Object[] arguments) {
235-
if (arguments[INDEX_GENERATOR_FRAME] instanceof MaterializedFrame) {
236-
return getGeneratorFrame(arguments);
237-
} else {
238-
return null;
239-
}
240-
}
241-
242-
public static void setGeneratorFrame(Object[] arguments, MaterializedFrame generatorFrame) {
243-
arguments[INDEX_GENERATOR_FRAME] = generatorFrame;
244-
}
245-
246214
/**
247215
* Synchronizes the arguments array of a Truffle frame with a {@link PFrame}. Copies only those
248216
* arguments that are necessary to be synchronized between the two.

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

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@
8181
import com.oracle.graal.python.runtime.PythonOptions;
8282
import com.oracle.graal.python.runtime.exception.PException;
8383
import com.oracle.graal.python.runtime.object.PFactory;
84-
import com.oracle.graal.python.util.PythonUtils;
8584
import com.oracle.truffle.api.Truffle;
8685
import com.oracle.truffle.api.bytecode.ContinuationResult;
8786
import com.oracle.truffle.api.dsl.Bind;
@@ -103,36 +102,6 @@
103102

104103
@CoreFunctions(extendClasses = {PythonBuiltinClassType.PCoroutine, PythonBuiltinClassType.PGenerator})
105104
public final class CommonGeneratorBuiltins extends PythonBuiltins {
106-
/**
107-
* Creates a fresh copy of the generator arguments to be used for the next invocation of the
108-
* generator. This is necessary to avoid persisting caller state. For example: If the generator
109-
* is invoked using {@code next(g)} outside of any {@code except} handler but the generator
110-
* requests the exception state, then the exception state will be written into the arguments. If
111-
* we now use the same arguments array every time, the next invocation would think that there is
112-
* not an exception but in fact, a subsequent call to {@code next} may have a different
113-
* exception state.
114-
*
115-
* <pre>
116-
* g = my_generator()
117-
*
118-
* # invoke without any exception context
119-
* next(g)
120-
*
121-
* try:
122-
* raise ValueError
123-
* except ValueError:
124-
* # invoke with exception context
125-
* next(g)
126-
* </pre>
127-
*
128-
* This is necessary for correct chaining of exceptions.
129-
*/
130-
private static Object[] prepareArguments(PGenerator self) {
131-
Object[] generatorArguments = self.getArguments();
132-
Object[] arguments = new Object[generatorArguments.length];
133-
PythonUtils.arraycopy(generatorArguments, 0, arguments, 0, arguments.length);
134-
return arguments;
135-
}
136105

137106
@Override
138107
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
@@ -168,10 +137,7 @@ static Object cached(VirtualFrame frame, Node inliningTarget, PGenerator self, O
168137
@Exclusive @Cached IsBuiltinObjectProfile errorProfile,
169138
@Exclusive @Cached PRaiseNode raiseNode) {
170139
self.setRunning(true);
171-
Object[] arguments = prepareArguments(self);
172-
if (sendValue != null) {
173-
PArguments.setSpecialArgument(arguments, sendValue);
174-
}
140+
Object[] arguments = self.getCallArguments(sendValue);
175141
GeneratorYieldResult result;
176142
try {
177143
result = (GeneratorYieldResult) invoke.execute(frame, inliningTarget, callNode, arguments);
@@ -221,7 +187,7 @@ static Object cachedBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGenera
221187

222188
if (firstCall) {
223189
// First invocation: call the regular root node.
224-
arguments = prepareArguments(self);
190+
arguments = self.getCallArguments(sendValue);
225191
} else {
226192
// Subsequent invocations: call a continuation root node.
227193
arguments = new Object[]{continuation.getFrame(), sendValue};
@@ -249,10 +215,7 @@ static Object generic(VirtualFrame frame, Node inliningTarget, PGenerator self,
249215
@Exclusive @Cached IsBuiltinObjectProfile errorProfile,
250216
@Exclusive @Cached PRaiseNode raiseNode) {
251217
self.setRunning(true);
252-
Object[] arguments = prepareArguments(self);
253-
if (sendValue != null) {
254-
PArguments.setSpecialArgument(arguments, sendValue);
255-
}
218+
Object[] arguments = self.getCallArguments(sendValue);
256219
GeneratorYieldResult result;
257220
try {
258221
result = (GeneratorYieldResult) invoke.execute(frame, inliningTarget, self.getCurrentCallTarget(), arguments);
@@ -282,7 +245,7 @@ static Object genericBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGener
282245
Object[] arguments;
283246
if (firstInvocationProfile.profile(inliningTarget, continuation == null)) {
284247
// First invocation: call the regular root node.
285-
arguments = prepareArguments(self);
248+
arguments = self.getCallArguments(sendValue);
286249
} else {
287250
// Subsequent invocations: call a continuation root node.
288251
arguments = new Object[]{continuation.getFrame(), sendValue};
@@ -418,7 +381,7 @@ static Object sendThrow(VirtualFrame frame, PGenerator self, Object typ, Object
418381
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
419382
generatorFrame = Truffle.getRuntime().createMaterializedFrame(PArguments.create(), self.getRootNode().getFrameDescriptor());
420383
} else {
421-
generatorFrame = PArguments.getGeneratorFrame(self.getArguments());
384+
generatorFrame = self.getGeneratorFrame();
422385
}
423386
PFrame pFrame = MaterializeFrameNode.materializeGeneratorFrame(location, generatorFrame, PFrame.Reference.EMPTY);
424387
FrameInfo info = (FrameInfo) generatorFrame.getFrameDescriptor().getInfo();

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,15 @@
3636
import java.util.List;
3737

3838
import com.oracle.graal.python.PythonLanguage;
39+
import com.oracle.graal.python.annotations.Builtin;
3940
import com.oracle.graal.python.annotations.Slot;
4041
import com.oracle.graal.python.annotations.Slot.SlotKind;
41-
import com.oracle.graal.python.annotations.Builtin;
4242
import com.oracle.graal.python.builtins.CoreFunctions;
4343
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4444
import com.oracle.graal.python.builtins.PythonBuiltins;
4545
import com.oracle.graal.python.builtins.objects.PNone;
4646
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
4747
import com.oracle.graal.python.builtins.objects.frame.PFrame;
48-
import com.oracle.graal.python.builtins.objects.function.PArguments;
4948
import com.oracle.graal.python.builtins.objects.str.StringNodes;
5049
import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode;
5150
import com.oracle.graal.python.builtins.objects.type.TpSlots;
@@ -227,7 +226,7 @@ static Object getFrame(PGenerator self) {
227226
if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
228227
return getBytecodeDSLMateriazedFrame(self);
229228
} else {
230-
MaterializedFrame generatorFrame = PArguments.getGeneratorFrame(self.getArguments());
229+
MaterializedFrame generatorFrame = self.getGeneratorFrame();
231230
BytecodeFrameInfo info = (BytecodeFrameInfo) generatorFrame.getFrameDescriptor().getInfo();
232231
PFrame frame = MaterializeFrameNode.materializeGeneratorFrame(info.getRootNode(), generatorFrame, PFrame.Reference.EMPTY);
233232
int bci = self.getBci();

0 commit comments

Comments
 (0)