|
81 | 81 | import com.oracle.graal.python.runtime.PythonOptions;
|
82 | 82 | import com.oracle.graal.python.runtime.exception.PException;
|
83 | 83 | import com.oracle.graal.python.runtime.object.PFactory;
|
84 |
| -import com.oracle.graal.python.util.PythonUtils; |
85 | 84 | import com.oracle.truffle.api.Truffle;
|
86 | 85 | import com.oracle.truffle.api.bytecode.ContinuationResult;
|
87 | 86 | import com.oracle.truffle.api.dsl.Bind;
|
|
103 | 102 |
|
104 | 103 | @CoreFunctions(extendClasses = {PythonBuiltinClassType.PCoroutine, PythonBuiltinClassType.PGenerator})
|
105 | 104 | 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 |
| - } |
136 | 105 |
|
137 | 106 | @Override
|
138 | 107 | protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
|
@@ -168,10 +137,7 @@ static Object cached(VirtualFrame frame, Node inliningTarget, PGenerator self, O
|
168 | 137 | @Exclusive @Cached IsBuiltinObjectProfile errorProfile,
|
169 | 138 | @Exclusive @Cached PRaiseNode raiseNode) {
|
170 | 139 | self.setRunning(true);
|
171 |
| - Object[] arguments = prepareArguments(self); |
172 |
| - if (sendValue != null) { |
173 |
| - PArguments.setSpecialArgument(arguments, sendValue); |
174 |
| - } |
| 140 | + Object[] arguments = self.getCallArguments(sendValue); |
175 | 141 | GeneratorYieldResult result;
|
176 | 142 | try {
|
177 | 143 | result = (GeneratorYieldResult) invoke.execute(frame, inliningTarget, callNode, arguments);
|
@@ -221,7 +187,7 @@ static Object cachedBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGenera
|
221 | 187 |
|
222 | 188 | if (firstCall) {
|
223 | 189 | // First invocation: call the regular root node.
|
224 |
| - arguments = prepareArguments(self); |
| 190 | + arguments = self.getCallArguments(sendValue); |
225 | 191 | } else {
|
226 | 192 | // Subsequent invocations: call a continuation root node.
|
227 | 193 | arguments = new Object[]{continuation.getFrame(), sendValue};
|
@@ -249,10 +215,7 @@ static Object generic(VirtualFrame frame, Node inliningTarget, PGenerator self,
|
249 | 215 | @Exclusive @Cached IsBuiltinObjectProfile errorProfile,
|
250 | 216 | @Exclusive @Cached PRaiseNode raiseNode) {
|
251 | 217 | self.setRunning(true);
|
252 |
| - Object[] arguments = prepareArguments(self); |
253 |
| - if (sendValue != null) { |
254 |
| - PArguments.setSpecialArgument(arguments, sendValue); |
255 |
| - } |
| 218 | + Object[] arguments = self.getCallArguments(sendValue); |
256 | 219 | GeneratorYieldResult result;
|
257 | 220 | try {
|
258 | 221 | result = (GeneratorYieldResult) invoke.execute(frame, inliningTarget, self.getCurrentCallTarget(), arguments);
|
@@ -282,7 +245,7 @@ static Object genericBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGener
|
282 | 245 | Object[] arguments;
|
283 | 246 | if (firstInvocationProfile.profile(inliningTarget, continuation == null)) {
|
284 | 247 | // First invocation: call the regular root node.
|
285 |
| - arguments = prepareArguments(self); |
| 248 | + arguments = self.getCallArguments(sendValue); |
286 | 249 | } else {
|
287 | 250 | // Subsequent invocations: call a continuation root node.
|
288 | 251 | arguments = new Object[]{continuation.getFrame(), sendValue};
|
@@ -418,7 +381,7 @@ static Object sendThrow(VirtualFrame frame, PGenerator self, Object typ, Object
|
418 | 381 | if (PythonOptions.ENABLE_BYTECODE_DSL_INTERPRETER) {
|
419 | 382 | generatorFrame = Truffle.getRuntime().createMaterializedFrame(PArguments.create(), self.getRootNode().getFrameDescriptor());
|
420 | 383 | } else {
|
421 |
| - generatorFrame = PArguments.getGeneratorFrame(self.getArguments()); |
| 384 | + generatorFrame = self.getGeneratorFrame(); |
422 | 385 | }
|
423 | 386 | PFrame pFrame = MaterializeFrameNode.materializeGeneratorFrame(location, generatorFrame, PFrame.Reference.EMPTY);
|
424 | 387 | FrameInfo info = (FrameInfo) generatorFrame.getFrameDescriptor().getInfo();
|
|
0 commit comments