/* --- Generators --------------------------------------------------------- */
-/* _PyGenObject_HEAD defines the initial segment of generator
- and coroutine objects. */
-#define _PyGenObject_HEAD(prefix) \
- PyObject_HEAD \
- /* List of weak reference. */ \
- PyObject *prefix##_weakreflist; \
- /* Name of the generator. */ \
- PyObject *prefix##_name; \
- /* Qualified name of the generator. */ \
- PyObject *prefix##_qualname; \
- _PyErr_StackItem prefix##_exc_state; \
- PyObject *prefix##_origin_or_finalizer; \
- char prefix##_hooks_inited; \
- char prefix##_closed; \
- char prefix##_running_async; \
- /* The frame */ \
- int8_t prefix##_frame_state; \
- PyObject *prefix##_iframe[1]; \
-
-typedef struct {
- /* The gi_ prefix is intended to remind of generator-iterator. */
- _PyGenObject_HEAD(gi)
-} PyGenObject;
+typedef struct _PyGenObject PyGenObject;
PyAPI_DATA(PyTypeObject) PyGen_Type;
/* --- PyCoroObject ------------------------------------------------------- */
-typedef struct {
- _PyGenObject_HEAD(cr)
-} PyCoroObject;
+typedef struct _PyCoroObject PyCoroObject;
PyAPI_DATA(PyTypeObject) PyCoro_Type;
/* --- Asynchronous Generators -------------------------------------------- */
-typedef struct {
- _PyGenObject_HEAD(ag)
-} PyAsyncGenObject;
+typedef struct _PyAsyncGenObject PyAsyncGenObject;
PyAPI_DATA(PyTypeObject) PyAsyncGen_Type;
PyAPI_DATA(PyTypeObject) _PyAsyncGenASend_Type;
#define PyAsyncGenASend_CheckExact(op) Py_IS_TYPE((op), &_PyAsyncGenASend_Type)
-
#undef _PyGenObject_HEAD
#ifdef __cplusplus
return frame;
}
-static inline
-PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame)
-{
- assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
- size_t offset_in_gen = offsetof(PyGenObject, gi_iframe);
- return (PyGenObject *)(((char *)frame) - offset_in_gen);
-}
-
PyAPI_FUNC(_PyInterpreterFrame *)
_PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
PyObject *locals, PyObject* const* args,
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_freelist.h"
+#include "pycore_frame.h"
+
+/* _PyGenObject_HEAD defines the initial segment of generator
+ and coroutine objects. */
+#define _PyGenObject_HEAD(prefix) \
+ PyObject_HEAD \
+ /* List of weak reference. */ \
+ PyObject *prefix##_weakreflist; \
+ /* Name of the generator. */ \
+ PyObject *prefix##_name; \
+ /* Qualified name of the generator. */ \
+ PyObject *prefix##_qualname; \
+ _PyErr_StackItem prefix##_exc_state; \
+ PyObject *prefix##_origin_or_finalizer; \
+ char prefix##_hooks_inited; \
+ char prefix##_closed; \
+ char prefix##_running_async; \
+ /* The frame */ \
+ int8_t prefix##_frame_state; \
+ struct _PyInterpreterFrame prefix##_iframe; \
+
+struct _PyGenObject {
+ /* The gi_ prefix is intended to remind of generator-iterator. */
+ _PyGenObject_HEAD(gi)
+};
+
+struct _PyCoroObject {
+ _PyGenObject_HEAD(cr)
+};
+
+struct _PyAsyncGenObject {
+ _PyGenObject_HEAD(ag)
+};
+
+#undef _PyGenObject_HEAD
+
+static inline
+PyGenObject *_PyGen_GetGeneratorFromFrame(_PyInterpreterFrame *frame)
+{
+ assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
+ size_t offset_in_gen = offsetof(PyGenObject, gi_iframe);
+ return (PyGenObject *)(((char *)frame) - offset_in_gen);
+}
PyAPI_FUNC(PyObject *)_PyGen_yf(PyGenObject *);
extern void _PyGen_Finalize(PyObject *self);
#include "pycore_floatobject.h" // struct _Py_float_state
#include "pycore_function.h" // FUNC_MAX_WATCHERS
#include "pycore_gc.h" // struct _gc_runtime_state
-#include "pycore_genobject.h" // struct _Py_async_gen_state
+#include "pycore_genobject.h" // _PyGen_FetchStopIterationValue
#include "pycore_global_objects.h"// struct _Py_interp_cached_objects
#include "pycore_import.h" // struct _import_state
#include "pycore_instruments.h" // _PY_MONITORING_EVENTS
{
assert(!_PyFrame_IsIncomplete(frame->f_frame));
if (frame->f_frame->owner == FRAME_OWNED_BY_GENERATOR) {
- PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame);
+ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame->f_frame);
return FRAME_STATE_SUSPENDED(gen->gi_frame_state);
}
return false;
frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
{
if (f->f_frame->owner == FRAME_OWNED_BY_GENERATOR) {
- PyGenObject *gen = _PyFrame_GetGenerator(f->f_frame);
+ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(f->f_frame);
if (gen->gi_frame_state == FRAME_EXECUTING) {
goto running;
}
if (frame->f_frame->owner != FRAME_OWNED_BY_GENERATOR) {
return NULL;
}
- PyGenObject *gen = _PyFrame_GetGenerator(frame->f_frame);
+ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame->f_frame);
return Py_NewRef(gen);
}
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_EvalFrame()
#include "pycore_frame.h" // _PyInterpreterFrame
+#include "pycore_freelist.h" // struct _Py_async_gen_freelist
#include "pycore_gc.h" // _PyGC_CLEAR_FINALIZED()
-#include "pycore_genobject.h" // struct _Py_async_gen_freelist
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
#include "pycore_opcode_utils.h" // RESUME_AFTER_YIELD_FROM
/* Returns a borrowed reference */
static inline PyCodeObject *
_PyGen_GetCode(PyGenObject *gen) {
- _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe);
- return _PyFrame_GetCode(frame);
+ return _PyFrame_GetCode(&gen->gi_iframe);
}
PyCodeObject *
Py_VISIT(gen->gi_name);
Py_VISIT(gen->gi_qualname);
if (gen->gi_frame_state != FRAME_CLEARED) {
- _PyInterpreterFrame *frame = (_PyInterpreterFrame *)(gen->gi_iframe);
+ _PyInterpreterFrame *frame = &gen->gi_iframe;
assert(frame->frame_obj == NULL ||
frame->frame_obj->f_frame->owner == FRAME_OWNED_BY_GENERATOR);
int err = _PyFrame_Traverse(frame, visit, arg);
Py_CLEAR(((PyAsyncGenObject*)gen)->ag_origin_or_finalizer);
}
if (gen->gi_frame_state != FRAME_CLEARED) {
- _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *frame = &gen->gi_iframe;
gen->gi_frame_state = FRAME_CLEARED;
frame->previous = NULL;
_PyFrame_ClearExceptCode(frame);
int exc, int closing)
{
PyThreadState *tstate = _PyThreadState_GET();
- _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *frame = &gen->gi_iframe;
*presult = NULL;
if (gen->gi_frame_state == FRAME_CREATED && arg && arg != Py_None) {
_PyGen_yf(PyGenObject *gen)
{
if (gen->gi_frame_state == FRAME_SUSPENDED_YIELD_FROM) {
- _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *frame = &gen->gi_iframe;
assert(is_resume(frame->instr_ptr));
assert((frame->instr_ptr->op.arg & RESUME_OPARG_LOCATION_MASK) >= RESUME_AFTER_YIELD_FROM);
return Py_NewRef(_PyFrame_StackPeek(frame));
gen->gi_frame_state = state;
Py_DECREF(yf);
}
- _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *frame = &gen->gi_iframe;
if (is_resume(frame->instr_ptr)) {
/* We can safely ignore the outermost try block
* as it is automatically generated to handle
// RESUME after YIELD_VALUE and exception depth is 1
assert((oparg & RESUME_OPARG_LOCATION_MASK) != RESUME_AT_FUNC_START);
gen->gi_frame_state = FRAME_COMPLETED;
- _PyFrame_ClearLocals((_PyInterpreterFrame *)gen->gi_iframe);
+ _PyFrame_ClearLocals(&gen->gi_iframe);
Py_RETURN_NONE;
}
}
PyObject *yf = _PyGen_yf(gen);
if (yf) {
- _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *frame = &gen->gi_iframe;
PyObject *ret;
int err;
if (PyErr_GivenExceptionMatches(typ, PyExc_GeneratorExit) &&
if (FRAME_STATE_FINISHED(gen->gi_frame_state)) {
Py_RETURN_NONE;
}
- return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject((_PyInterpreterFrame *)gen->gi_iframe));
+ return _Py_XNewRef((PyObject *)_PyFrame_GetFrameObject(&gen->gi_iframe));
}
static PyObject *
PyTypeObject PyGen_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"generator", /* tp_name */
- offsetof(PyGenObject, gi_iframe) +
- offsetof(_PyInterpreterFrame, localsplus), /* tp_basicsize */
+ sizeof(PyGenObject), /* tp_basicsize */
sizeof(PyObject *), /* tp_itemsize */
/* methods */
(destructor)gen_dealloc, /* tp_dealloc */
/* Copy the frame */
assert(f->f_frame->frame_obj == NULL);
assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT);
- _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *frame = &gen->gi_iframe;
_PyFrame_Copy((_PyInterpreterFrame *)f->_f_frame_data, frame);
gen->gi_frame_state = FRAME_CREATED;
assert(frame->frame_obj == f);
PyTypeObject PyCoro_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"coroutine", /* tp_name */
- offsetof(PyCoroObject, cr_iframe) +
- offsetof(_PyInterpreterFrame, localsplus), /* tp_basicsize */
+ sizeof(PyCoroObject), /* tp_basicsize */
sizeof(PyObject *), /* tp_itemsize */
/* methods */
(destructor)gen_dealloc, /* tp_dealloc */
PyTypeObject PyAsyncGen_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"async_generator", /* tp_name */
- offsetof(PyAsyncGenObject, ag_iframe) +
- offsetof(_PyInterpreterFrame, localsplus), /* tp_basicsize */
+ sizeof(PyAsyncGenObject), /* tp_basicsize */
sizeof(PyObject *), /* tp_itemsize */
/* methods */
(destructor)gen_dealloc, /* tp_dealloc */
((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING)
{
PyGenObject *gen = (PyGenObject *)receiver;
- _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *gen_frame = &gen->gi_iframe;
STACK_SHRINK(1);
_PyFrame_StackPush(gen_frame, v);
gen->gi_frame_state = FRAME_EXECUTING;
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type);
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING);
STAT_INC(SEND, hit);
- _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *gen_frame = &gen->gi_iframe;
STACK_SHRINK(1);
_PyFrame_StackPush(gen_frame, v);
gen->gi_frame_state = FRAME_EXECUTING;
inst(INSTRUMENTED_YIELD_VALUE, (retval -- unused)) {
assert(frame != &entry_frame);
frame->instr_ptr = next_instr;
- PyGenObject *gen = _PyFrame_GetGenerator(frame);
+ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
assert(oparg == 0 || oparg == 1);
gen->gi_frame_state = FRAME_SUSPENDED + oparg;
assert(frame != &entry_frame);
#endif
frame->instr_ptr++;
- PyGenObject *gen = _PyFrame_GetGenerator(frame);
+ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
assert(oparg == 0 || oparg == 1);
gen->gi_frame_state = FRAME_SUSPENDED + oparg;
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type);
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING);
STAT_INC(FOR_ITER, hit);
- gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ gen_frame = &gen->gi_iframe;
_PyFrame_StackPush(gen_frame, Py_None);
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
}
assert(EMPTY());
_PyFrame_SetStackPointer(frame, stack_pointer);
- _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *gen_frame = &gen->gi_iframe;
frame->instr_ptr++;
_PyFrame_Copy(frame, gen_frame);
assert(frame->frame_obj == NULL);
clear_gen_frame(PyThreadState *tstate, _PyInterpreterFrame * frame)
{
assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
- PyGenObject *gen = _PyFrame_GetGenerator(frame);
+ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
gen->gi_frame_state = FRAME_CLEARED;
assert(tstate->exc_info == &gen->gi_exc_state);
tstate->exc_info = gen->gi_exc_state.previous_item;
assert(frame != &entry_frame);
#endif
frame->instr_ptr++;
- PyGenObject *gen = _PyFrame_GetGenerator(frame);
+ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
assert(oparg == 0 || oparg == 1);
gen->gi_frame_state = FRAME_SUSPENDED + oparg;
JUMP_TO_JUMP_TARGET();
}
STAT_INC(FOR_ITER, hit);
- gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ gen_frame = &gen->gi_iframe;
_PyFrame_StackPush(gen_frame, Py_None);
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
}
assert(EMPTY());
_PyFrame_SetStackPointer(frame, stack_pointer);
- _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *gen_frame = &gen->gi_iframe;
frame->instr_ptr++;
_PyFrame_Copy(frame, gen_frame);
assert(frame->frame_obj == NULL);
/* It is the responsibility of the owning generator/coroutine
* to have cleared the enclosing generator, if any. */
assert(frame->owner != FRAME_OWNED_BY_GENERATOR ||
- _PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED);
+ _PyGen_GetGeneratorFromFrame(frame)->gi_frame_state == FRAME_CLEARED);
// GH-99729: Clearing this frame can expose the stack (via finalizers). It's
// crucial that this frame has been unlinked, and is no longer visible:
assert(_PyThreadState_GET()->current_frame != frame);
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER);
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER);
STAT_INC(FOR_ITER, hit);
- gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ gen_frame = &gen->gi_iframe;
_PyFrame_StackPush(gen_frame, Py_None);
gen->gi_frame_state = FRAME_EXECUTING;
gen->gi_exc_state.previous_item = tstate->exc_info;
retval = stack_pointer[-1];
assert(frame != &entry_frame);
frame->instr_ptr = next_instr;
- PyGenObject *gen = _PyFrame_GetGenerator(frame);
+ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
assert(oparg == 0 || oparg == 1);
gen->gi_frame_state = FRAME_SUSPENDED + oparg;
}
assert(EMPTY());
_PyFrame_SetStackPointer(frame, stack_pointer);
- _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *gen_frame = &gen->gi_iframe;
frame->instr_ptr++;
_PyFrame_Copy(frame, gen_frame);
assert(frame->frame_obj == NULL);
((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING)
{
PyGenObject *gen = (PyGenObject *)receiver;
- _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *gen_frame = &gen->gi_iframe;
STACK_SHRINK(1);
_PyFrame_StackPush(gen_frame, v);
gen->gi_frame_state = FRAME_EXECUTING;
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type, SEND);
DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND);
STAT_INC(SEND, hit);
- _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe;
+ _PyInterpreterFrame *gen_frame = &gen->gi_iframe;
STACK_SHRINK(1);
_PyFrame_StackPush(gen_frame, v);
gen->gi_frame_state = FRAME_EXECUTING;
assert(frame != &entry_frame);
#endif
frame->instr_ptr++;
- PyGenObject *gen = _PyFrame_GetGenerator(frame);
+ PyGenObject *gen = _PyGen_GetGeneratorFromFrame(frame);
assert(FRAME_SUSPENDED_YIELD_FROM == FRAME_SUSPENDED + 1);
assert(oparg == 0 || oparg == 1);
gen->gi_frame_state = FRAME_SUSPENDED + oparg;
#include "pycore_exceptions.h" // _PyExc_InitTypes()
#include "pycore_fileutils.h" // _Py_ResetForceASCII()
#include "pycore_floatobject.h" // _PyFloat_InitTypes()
-#include "pycore_genobject.h" // _PyAsyncGen_Fini()
#include "pycore_global_objects_fini_generated.h" // "_PyStaticObjects_CheckRefcnt()
#include "pycore_import.h" // _PyImport_BootstrapImp()
#include "pycore_initconfig.h" // _PyStatus_OK()