|
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