8000 Add asserts back and teach is_resume about ENTER_EXECUTOR · python/cpython@ba3d68b · GitHub
[go: up one dir, main page]

Skip to content

Commit ba3d68b

Browse files
committed
Add asserts back and teach is_resume about ENTER_EXECUTOR
1 parent 511ec09 commit ba3d68b

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

Objects/genobject.c

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "pycore_gc.h" // _PyGC_CLEAR_FINALIZED()
1111
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
1212
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
13+
#include "pycore_opcode_metadata.h" // _PyOpcode_Deopt
1314
#include "pycore_opcode_utils.h" // RESUME_AFTER_YIELD_FROM
1415
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_*
1516
#include "pycore_pyerrors.h" // _PyErr_ClearExcState()
@@ -327,21 +328,35 @@ gen_close_iter(PyObject *yf)
327328
}
328329

329330
static inline bool
330-
is_resume(_Py_CODEUNIT *instr)
331+
is_resume(_PyInterpreterFrame *frame, uint8_t *oparg_p)
331332
{
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;
338348
}
339349

340350
PyObject *
341351
_PyGen_yf(PyGenObject *gen)
342352
{
343353
if (gen->gi_frame_state == FRAME_SUSPENDED_YIELD_FROM) {
344354
_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
345360
return PyStackRef_AsPyObjectNew(_PyFrame_StackPeek(frame));
346361
}
347362
return NULL;
@@ -370,11 +385,11 @@ gen_close(PyGenObject *gen, PyObject *args)
370385
Py_DECREF(yf);
371386
}
372387
_PyInterpreterFrame *frame = &gen->gi_iframe;
373-
if (is_resume(frame->instr_ptr)) {
388+
uint8_t oparg;
389+
if (is_resume(frame, &oparg)) {
374390
/* We can safely ignore the outermost try block
375391
* as it is automatically generated to handle
376392
* StopIteration. */
377-
int oparg = frame->instr_ptr->op.arg;
378393
if (oparg & RESUME_OPARG_DEPTH1_MASK) {
379394
// RESUME after YIELD_VALUE and exception depth is 1
380395
assert((oparg & RESUME_OPARG_LOCATION_MASK) != RESUME_AT_FUNC_START);

0 commit comments

Comments
 (0)
0