[FORMAT_SIMPLE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[FORMAT_WITH_SPEC] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[FOR_ITER] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG },
- [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
+ [FOR_ITER_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
[FOR_ITER_LIST] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG },
[FOR_ITER_RANGE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG },
[FOR_ITER_TUPLE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EXIT_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG },
[RETURN_GENERATOR] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
[RETURN_VALUE] = { true, INSTR_FMT_IX, HAS_ESCAPES_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
[SEND] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_UNPREDICTABLE_JUMP_FLAG | HAS_NEEDS_GUARD_IP_FLAG },
- [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
+ [SEND_GEN] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_SYNC_SP_FLAG | HAS_NEEDS_GUARD_IP_FLAG | HAS_RECORDS_VALUE_FLAG },
[SETUP_ANNOTATIONS] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[SET_ADD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[SET_FUNCTION_ATTRIBUTE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[_RECORD_TOS] = HAS_RECORDS_VALUE_FLAG,
[_RECORD_TOS_TYPE] = HAS_RECORDS_VALUE_FLAG,
[_RECORD_NOS] = HAS_RECORDS_VALUE_FLAG,
- [_RECORD_NOS_GEN_FUNC] = HAS_ESCAPES_FLAG | HAS_RECORDS_VALUE_FLAG,
+ [_RECORD_NOS_GEN_FUNC] = HAS_RECORDS_VALUE_FLAG,
[_RECORD_4OS] = HAS_RECORDS_VALUE_FLAG,
[_RECORD_CALLABLE] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG,
[_RECORD_BOUND_METHOD] = HAS_ARG_FLAG | HAS_RECORDS_VALUE_FLAG,
PYTHON_JIT_SIDE_EXIT_INITIAL_VALUE="1")
self.assertEqual(result[0].rc, 0, result)
+ def test_for_iter_gen_cleared_frame_does_not_crash(self):
+ # See: https://github.com/python/cpython/issues/145197
+ result = script_helper.run_python_until_end('-c', textwrap.dedent("""
+ def g():
+ yield 1
+ yield 2
+
+ for _ in range(4002):
+ for _ in g():
+ pass
+
+ for i in range(4002):
+ it = g()
+ if (i & 7) == 0:
+ next(it)
+ it.close()
+ for _ in it:
+ pass
+ """),
+ PYTHON_JIT="1", PYTHON_JIT_STRESS="1")
+ self.assertEqual(result[0].rc, 0, result)
+
def global_identity(x):
return x
tier2 op(_RECORD_NOS_GEN_FUNC, (nos, tos -- nos, tos)) {
PyObject *obj = PyStackRef_AsPyObjectBorrow(nos);
if (PyGen_Check(obj)) {
- PyObject *func = (PyObject *)_PyFrame_GetFunction(&((PyGenObject *)obj)->gi_iframe);
- RECORD_VALUE(func);
+ PyGenObject *gen = (PyGenObject *)obj;
+ _PyStackRef func = gen->gi_iframe.f_funcobj;
+ if (!PyStackRef_IsNull(func)) {
+ RECORD_VALUE(PyStackRef_AsPyObjectBorrow(func));
+ }
}
}
nos = stack_pointer[-2];
PyObject *obj = PyStackRef_AsPyObjectBorrow(nos);
if (PyGen_Check(obj)) {
- _PyFrame_SetStackPointer(frame, stack_pointer);
- PyObject *func = (PyObject *)_PyFrame_GetFunction(&((PyGenObject *)obj)->gi_iframe);
- stack_pointer = _PyFrame_GetStackPointer(frame);
- *recorded_value = (PyObject *)func;
- Py_INCREF(*recorded_value);
+ PyGenObject *gen = (PyGenObject *)obj;
+ _PyStackRef func = gen->gi_iframe.f_funcobj;
+ if (!PyStackRef_IsNull(func)) {
+ *recorded_value = (PyObject *)PyStackRef_AsPyObjectBorrow(func);
+ Py_INCREF(*recorded_value);
+ }
}
}