|
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