|
67 | 67 | import com.oracle.graal.python.nodes.ErrorMessages; |
68 | 68 | import com.oracle.graal.python.nodes.PGuards; |
69 | 69 | import com.oracle.graal.python.nodes.PRaiseNode; |
| 70 | +import com.oracle.graal.python.nodes.PRootNode; |
70 | 71 | import com.oracle.graal.python.nodes.bytecode.FrameInfo; |
71 | 72 | import com.oracle.graal.python.nodes.bytecode.GeneratorReturnException; |
72 | 73 | import com.oracle.graal.python.nodes.bytecode.GeneratorYieldResult; |
|
77 | 78 | import com.oracle.graal.python.nodes.function.builtins.PythonQuaternaryBuiltinNode; |
78 | 79 | import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; |
79 | 80 | import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; |
| 81 | +import com.oracle.graal.python.runtime.ExecutionContext; |
80 | 82 | import com.oracle.graal.python.runtime.PythonOptions; |
81 | 83 | import com.oracle.graal.python.runtime.exception.PException; |
82 | 84 | import com.oracle.graal.python.runtime.object.PFactory; |
| 85 | +import com.oracle.truffle.api.RootCallTarget; |
83 | 86 | import com.oracle.truffle.api.bytecode.ContinuationResult; |
| 87 | +import com.oracle.truffle.api.bytecode.ContinuationRootNode; |
84 | 88 | import com.oracle.truffle.api.dsl.Bind; |
85 | 89 | import com.oracle.truffle.api.dsl.Cached; |
86 | 90 | import com.oracle.truffle.api.dsl.Cached.Exclusive; |
|
94 | 98 | import com.oracle.truffle.api.frame.MaterializedFrame; |
95 | 99 | import com.oracle.truffle.api.frame.VirtualFrame; |
96 | 100 | import com.oracle.truffle.api.nodes.DirectCallNode; |
| 101 | +import com.oracle.truffle.api.nodes.IndirectCallNode; |
97 | 102 | import com.oracle.truffle.api.nodes.Node; |
98 | 103 | import com.oracle.truffle.api.profiles.InlinedBranchProfile; |
99 | 104 | import com.oracle.truffle.api.profiles.InlinedConditionProfile; |
@@ -153,16 +158,31 @@ static Object cached(VirtualFrame frame, Node inliningTarget, PGenerator self, O |
153 | 158 | @Specialization(guards = {"isBytecodeDSLInterpreter()", "sameCallTarget(self.getCurrentCallTarget(), callNode)"}, limit = "getCallSiteInlineCacheMaxDepth()") |
154 | 159 | static Object cachedBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGenerator self, Object sendValue, |
155 | 160 | @Cached(parameters = "self.getCurrentCallTarget()") DirectCallNode callNode, |
156 | | - @Exclusive @Cached CallDispatchers.SimpleDirectInvokeNode invoke, |
| 161 | + @Exclusive @Cached ExecutionContext.CallContext callContext, |
157 | 162 | @Exclusive @Cached InlinedBranchProfile returnProfile, |
158 | 163 | @Exclusive @Cached IsBuiltinObjectProfile errorProfile, |
159 | 164 | @Exclusive @Cached PRaiseNode raiseNode) { |
160 | 165 | self.setRunning(true); |
161 | 166 | Object generatorResult; |
162 | 167 | try { |
163 | 168 | self.prepareResume(); |
164 | | - Object[] arguments = new Object[]{self.getGeneratorFrame(), sendValue}; |
165 | | - generatorResult = invoke.execute(frame, inliningTarget, callNode, arguments); |
| 169 | + RootCallTarget callTarget = (RootCallTarget) callNode.getCurrentCallTarget(); |
| 170 | + PRootNode rootNode = PGenerator.unwrapContinuationRoot((ContinuationRootNode) callTarget.getRootNode()); |
| 171 | + /* |
| 172 | + * When resuming a generator/coroutine, the call target is a ContinuationRoot with a |
| 173 | + * different calling convention from regular PRootNodes. The first argument is a |
| 174 | + * materialized frame, which will be used for the execution itself. We will, e.g., |
| 175 | + * lookup the exception state in that frame's arguments. |
| 176 | + * |
| 177 | + * So for Bytecode DSL generators, we update the arguments array of that |
| 178 | + * materialized frame instead of the arguments array that will be used for the |
| 179 | + * actual Truffle call to the ContinuationRoot, which is not accessible to us in the |
| 180 | + * generator root. |
| 181 | + */ |
| 182 | + MaterializedFrame generatorFrame = self.getGeneratorFrame(); |
| 183 | + callContext.executePrepareCall(frame, generatorFrame.getArguments(), rootNode.needsCallerFrame(), rootNode.needsExceptionState()); |
| 184 | + Object[] arguments = new Object[]{generatorFrame, sendValue}; |
| 185 | + generatorResult = callNode.call(arguments); |
166 | 186 | } catch (PException e) { |
167 | 187 | throw handleException(self, inliningTarget, errorProfile, raiseNode, e); |
168 | 188 | } finally { |
@@ -203,16 +223,22 @@ static Object generic(VirtualFrame frame, Node inliningTarget, PGenerator self, |
203 | 223 | @Specialization(replaces = "cachedBytecodeDSL", guards = "isBytecodeDSLInterpreter()") |
204 | 224 | @Megamorphic |
205 | 225 | static Object genericBytecodeDSL(VirtualFrame frame, Node inliningTarget, PGenerator self, Object sendValue, |
206 | | - @Exclusive @Cached CallDispatchers.SimpleIndirectInvokeNode invoke, |
| 226 | + @Exclusive @Cached ExecutionContext.CallContext callContext, |
| 227 | + @Exclusive @Cached IndirectCallNode callNode, |
207 | 228 | @Exclusive @Cached InlinedBranchProfile returnProfile, |
208 | 229 | @Exclusive @Cached IsBuiltinObjectProfile errorProfile, |
209 | 230 | @Exclusive @Cached PRaiseNode raiseNode) { |
210 | 231 | self.setRunning(true); |
211 | 232 | Object generatorResult; |
212 | 233 | try { |
213 | 234 | self.prepareResume(); |
214 | | - Object[] arguments = new Object[]{self.getGeneratorFrame(), sendValue}; |
215 | | - generatorResult = invoke.execute(frame, inliningTarget, self.getCurrentCallTarget(), arguments); |
| 235 | + RootCallTarget callTarget = self.getCurrentCallTarget(); |
| 236 | + // See the cached specialization for notes about the arguments handling |
| 237 | + PRootNode rootNode = PGenerator.unwrapContinuationRoot((ContinuationRootNode) callTarget.getRootNode()); |
| 238 | + MaterializedFrame generatorFrame = self.getGeneratorFrame(); |
| 239 | + callContext.executePrepareCall(frame, generatorFrame.getArguments(), rootNode.needsCallerFrame(), rootNode.needsExceptionState()); |
| 240 | + Object[] arguments = new Object[]{generatorFrame, sendValue}; |
| 241 | + generatorResult = callNode.call(callTarget, arguments); |
216 | 242 | } catch (PException e) { |
217 | 243 | throw handleException(self, inliningTarget, errorProfile, raiseNode, e); |
218 | 244 | } finally { |
|
0 commit comments