https://github.com/python/cpython/commit/61317074d450f72fa121ceb1c7b0c52698a71106 commit: 61317074d450f72fa121ceb1c7b0c52698a71106 branch: main author: Victor Stinner <vstin...@python.org> committer: vstinner <vstin...@python.org> date: 2025-03-21T17:19:47Z summary:
gh-131238: Add pycore_interpframe_structs.h header (#131553) Add an explicit include to pycore_interpframe_structs.h in pycore_runtime_structs.h to fix a dependency cycle. files: A Include/internal/pycore_interpframe_structs.h M Include/internal/pycore_genobject.h M Include/internal/pycore_interpframe.h M Include/internal/pycore_runtime_structs.h M Objects/genobject.c M Python/pylifecycle.c M Python/pystate.c diff --git a/Include/internal/pycore_genobject.h b/Include/internal/pycore_genobject.h index e99ffcba64e66f..2947dde71fd676 100644 --- a/Include/internal/pycore_genobject.h +++ b/Include/internal/pycore_genobject.h @@ -9,42 +9,9 @@ extern "C" { #endif #include "pycore_interpframe.h" // _PyInterpreterFrame +#include "pycore_interpframe_structs.h" // _PyGenObject -/* _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; \ - _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) { diff --git a/Include/internal/pycore_interpframe.h b/Include/internal/pycore_interpframe.h index f513dbe5cbbdb3..41acd877aee873 100644 --- a/Include/internal/pycore_interpframe.h +++ b/Include/internal/pycore_interpframe.h @@ -1,7 +1,3 @@ -/* See InternalDocs/frames.md for an explanation of the frame stack - * including explanation of the PyFrameObject and _PyInterpreterFrame - * structs. */ - #ifndef Py_INTERNAL_INTERP_FRAME_H #define Py_INTERNAL_INTERP_FRAME_H @@ -10,50 +6,14 @@ #endif #include "pycore_code.h" // _PyCode_CODE() +#include "pycore_interpframe_structs.h" // _PyInterpreterFrame #include "pycore_stackref.h" // PyStackRef_AsPyObjectBorrow() #include "pycore_stats.h" // CALL_STAT_INC() -#include "pycore_structs.h" // _PyStackRef -#include "pycore_typedefs.h" // _PyInterpreterFrame - #ifdef __cplusplus extern "C" { #endif -enum _frameowner { - FRAME_OWNED_BY_THREAD = 0, - FRAME_OWNED_BY_GENERATOR = 1, - FRAME_OWNED_BY_FRAME_OBJECT = 2, - FRAME_OWNED_BY_INTERPRETER = 3, - FRAME_OWNED_BY_CSTACK = 4, -}; - -struct _PyInterpreterFrame { - _PyStackRef f_executable; /* Deferred or strong reference (code object or None) */ - struct _PyInterpreterFrame *previous; - _PyStackRef f_funcobj; /* Deferred or strong reference. Only valid if not on C stack */ - PyObject *f_globals; /* Borrowed reference. Only valid if not on C stack */ - PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack */ - PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on C stack */ - PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if not on C stack */ - _Py_CODEUNIT *instr_ptr; /* Instruction currently executing (or about to begin) */ - _PyStackRef *stackpointer; -#ifdef Py_GIL_DISABLED - /* Index of thread-local bytecode containing instr_ptr. */ - int32_t tlbc_index; -#endif - uint16_t return_offset; /* Only relevant during a function call */ - char owner; -#ifdef Py_DEBUG - uint8_t visited:1; - uint8_t lltrace:7; -#else - uint8_t visited; -#endif - /* Locals and stack */ - _PyStackRef localsplus[1]; -}; - #define _PyInterpreterFrame_LASTI(IF) \ ((int)((IF)->instr_ptr - _PyFrame_GetBytecode((IF)))) diff --git a/Include/internal/pycore_interpframe_structs.h b/Include/internal/pycore_interpframe_structs.h new file mode 100644 index 00000000000000..835b8e58194863 --- /dev/null +++ b/Include/internal/pycore_interpframe_structs.h @@ -0,0 +1,95 @@ +/* Structures used by pycore_debug_offsets.h. + * + * See InternalDocs/frames.md for an explanation of the frame stack + * including explanation of the PyFrameObject and _PyInterpreterFrame + * structs. + */ + +#ifndef Py_INTERNAL_INTERP_FRAME_STRUCTS_H +#define Py_INTERNAL_INTERP_FRAME_STRUCTS_H + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +#include "pycore_structs.h" // _PyStackRef +#include "pycore_typedefs.h" // _PyInterpreterFrame + +#ifdef __cplusplus +extern "C" { +#endif + +enum _frameowner { + FRAME_OWNED_BY_THREAD = 0, + FRAME_OWNED_BY_GENERATOR = 1, + FRAME_OWNED_BY_FRAME_OBJECT = 2, + FRAME_OWNED_BY_INTERPRETER = 3, + FRAME_OWNED_BY_CSTACK = 4, +}; + +struct _PyInterpreterFrame { + _PyStackRef f_executable; /* Deferred or strong reference (code object or None) */ + struct _PyInterpreterFrame *previous; + _PyStackRef f_funcobj; /* Deferred or strong reference. Only valid if not on C stack */ + PyObject *f_globals; /* Borrowed reference. Only valid if not on C stack */ + PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack */ + PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on C stack */ + PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if not on C stack */ + _Py_CODEUNIT *instr_ptr; /* Instruction currently executing (or about to begin) */ + _PyStackRef *stackpointer; +#ifdef Py_GIL_DISABLED + /* Index of thread-local bytecode containing instr_ptr. */ + int32_t tlbc_index; +#endif + uint16_t return_offset; /* Only relevant during a function call */ + char owner; +#ifdef Py_DEBUG + uint8_t visited:1; + uint8_t lltrace:7; +#else + uint8_t visited; +#endif + /* Locals and stack */ + _PyStackRef localsplus[1]; +}; + + +/* _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; \ + _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 + + +#ifdef __cplusplus +} +#endif +#endif // !Py_INTERNAL_INTERP_FRAME_STRUCTS_H diff --git a/Include/internal/pycore_runtime_structs.h b/Include/internal/pycore_runtime_structs.h index a062de39f4eb40..6bf3aae7175a97 100644 --- a/Include/internal/pycore_runtime_structs.h +++ b/Include/internal/pycore_runtime_structs.h @@ -64,6 +64,7 @@ struct _fileutils_state { int force_ascii; }; +#include "pycore_interpframe_structs.h" // _PyInterpreterFrame #include "pycore_debug_offsets.h" // _Py_DebugOffsets #include "pycore_signal.h" // struct _signals_runtime_state #include "pycore_faulthandler.h" // struct _faulthandler_runtime_state diff --git a/Objects/genobject.c b/Objects/genobject.c index 308d45701d296f..13f2bf7808c309 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -3,13 +3,12 @@ #define _PY_INTERPRETER #include "Python.h" -#include "pycore_genobject.h" - #include "pycore_call.h" // _PyObject_CallNoArgs() #include "pycore_ceval.h" // _PyEval_EvalFrame() #include "pycore_frame.h" // _PyInterpreterFrame #include "pycore_freelist.h" // _Py_FREELIST_FREE(), _Py_FREELIST_POP() #include "pycore_gc.h" // _PyGC_CLEAR_FINALIZED() +#include "pycore_genobject.h" #include "pycore_modsupport.h" // _PyArg_CheckPositional() #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_opcode_utils.h" // RESUME_AFTER_YIELD_FROM diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index ed21fce335c99d..484583e1c79579 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -1,8 +1,6 @@ /* Python interpreter top-level routines, including init/exit */ #include "Python.h" -#include "pycore_genobject.h" // included first to break dependency cycle - #include "pycore_audit.h" // _PySys_ClearAuditHooks() #include "pycore_call.h" // _PyObject_CallMethod() #include "pycore_ceval.h" // _PyEval_FiniGIL() diff --git a/Python/pystate.c b/Python/pystate.c index 7d1ca0d33ef4d8..ee35f0fa945f8b 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -2,8 +2,6 @@ /* Thread and interpreter state structures and their interfaces */ #include "Python.h" -#include "pycore_genobject.h" // included first to break dependency cycle - #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_audit.h" // _Py_AuditHookEntry #include "pycore_ceval.h" // _PyEval_AcquireLock() _______________________________________________ Python-checkins mailing list -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com