|
10 | 10 | #include "pycore_gc.h" // _PyGC_CLEAR_FINALIZED()
|
11 | 11 | #include "pycore_modsupport.h" // _PyArg_CheckPositional()
|
12 | 12 | #include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
| 13 | +#include "pycore_opcode_metadata.h" // _PyOpcode_Deopt |
13 | 14 | #include "pycore_opcode_utils.h" // RESUME_AFTER_YIELD_FROM
|
14 | 15 | #include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_*
|
15 | 16 | #include "pycore_pyerrors.h" // _PyErr_ClearExcState()
|
@@ -327,21 +328,35 @@ gen_close_iter(PyObject *yf)
|
327 | 328 | }
|
328 | 329 |
|
329 | 330 | static inline bool
|
330 |
| -is_resume(_Py_CODEUNIT *instr) |
| 331 | +is_resume(_PyInterpreterFrame *frame, uint8_t *oparg_p) |
331 | 332 | {
|
332 |
| - uint8_t code = FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.code); |
333 |
| - return ( |
334 |
| - code == RESUME || |
335 |
| - code == RESUME_CHECK || |
336 |
| - code == INSTRUMENTED_RESUME |
337 |
| - ); |
| 333 | + PyCodeObject *code = _PyFrame_GetCode(frame); |
| 334 | + int offset = frame->instr_ptr - _PyCode_CODE(code); |
| 335 | + uint8_t opcode = _Py_GetBaseOpcode(code, offset); |
| 336 | + uint8_t oparg = frame->instr_ptr->op.arg; |
| 337 | + if (opcode == ENTER_EXECUTOR) { |
| 338 | + _PyExecutorObject *executor = _Py_GetExecutor(code, sizeof(_Py_CODEUNIT) * offset); |
| 339 | + opcode = _PyOpcode_Deopt[executor->vm_data.opcode]; |
| 340 | + oparg = executor->vm_data.oparg; |
| 341 | + Py_DECREF(executor); |
| 342 | + } |
| 343 | + if (opcode == RESUME) { |
| 344 | + *oparg_p = oparg; |
| 345 | + return true; |
| 346 | + } |
| 347 | + return false; |
338 | 348 | }
|
339 | 349 |
|
340 | 350 | PyObject *
|
341 | 351 | _PyGen_yf(PyGenObject *gen)
|
342 | 352 | {
|
343 | 353 | if (gen->gi_frame_state == FRAME_SUSPENDED_YIELD_FROM) {
|
344 | 354 | _PyInterpreterFrame *frame = &gen->gi_iframe;
|
| 355 | + #ifndef NDEBUG |
| 356 | + uint8_t oparg; |
| 357 | + assert(is_resume(frame, &oparg)); |
| 358 | + assert((oparg & RESUME_OPARG_LOCATION_MASK) >= RESUME_AFTER_YIELD_FROM); |
| 359 | + #endif |
345 | 360 | return PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame));
|
346 | 361 | }
|
347 | 362 | return NULL;
|
@@ -370,11 +385,11 @@ gen_close(PyGenObject *gen, PyObject *args)
|
370 | 385 | Py_DECREF(yf);
|
371 | 386 | }
|
372 | 387 | _PyInterpreterFrame *frame = &gen->gi_iframe;
|
373 |
| - if (is_resume(frame->instr_ptr)) { |
| 388 | + uint8_t oparg; |
| 389 | + if (is_resume(frame, &oparg)) { |
374 | 390 | /* We can safely ignore the outermost try block
|
375 | 391 | * as it is automatically generated to handle
|
376 | 392 | * StopIteration. */
|
377 |
| - int oparg = frame->instr_ptr->op.arg; |
378 | 393 | if (oparg & RESUME_OPARG_DEPTH1_MASK) {
|
379 | 394 | // RESUME after YIELD_VALUE and exception depth is 1
|
380 | 395 | assert((oparg & RESUME_OPARG_LOCATION_MASK) != RESUME_AT_FUNC_START);
|
|
0 commit comments