@@ -61,32 +61,44 @@ enum _frameowner {
6161 FRAME_OWNED_BY_CSTACK = 4 ,
6262};
6363
64+ struct _PyFrameCore {
65+ _PyStackRef f_executable ; /* Deferred or strong reference */
66+ union _PyVMFrame * previous ;
67+ char owner ;
68+ };
69+
6470typedef struct _PyInterpreterFrame {
6571 _PyStackRef f_executable ; /* Deferred or strong reference (code object or None) */
66- struct _PyInterpreterFrame * previous ;
67- _PyStackRef f_funcobj ; /* Deferred or strong reference. Only valid if not on C stack */
68- PyObject * f_globals ; /* Borrowed reference. Only valid if not on C stack */
69- PyObject * f_builtins ; /* Borrowed reference. Only valid if not on C stack */
70- PyObject * f_locals ; /* Strong reference, may be NULL. Only valid if not on C stack */
71- PyFrameObject * frame_obj ; /* Strong reference, may be NULL. Only valid if not on C stack */
72- _Py_CODEUNIT * instr_ptr ; /* Instruction currently executing (or about to begin) */
73- _PyStackRef * stackpointer ;
74- #ifdef Py_GIL_DISABLED
75- /* Index of thread-local bytecode containing instr_ptr. */
76- int32_t tlbc_index ;
77- #endif
78- uint16_t return_offset ; /* Only relevant during a function call */
72+ union _PyVMFrame * previous ;
7973 char owner ;
8074#ifdef Py_DEBUG
8175 uint8_t visited :1 ;
8276 uint8_t lltrace :7 ;
8377#else
8478 uint8_t visited ;
8579#endif
80+ uint16_t return_offset ; /* Only relevant during a function call */
81+ #ifdef Py_GIL_DISABLED
82+ /* Index of thread-local bytecode containing instr_ptr. */
83+ int32_t tlbc_index ;
84+ #endif
85+ _PyStackRef f_funcobj ; /* Deferred or strong reference. Only valid if not on C stack */
86+ PyObject * f_globals ; /* Borrowed reference. Only valid if not on C stack */
87+ PyObject * f_builtins ; /* Borrowed reference. Only valid if not on C stack */
88+ PyObject * f_locals ; /* Strong reference, may be NULL. Only valid if not on C stack */
89+ PyFrameObject * frame_obj ; /* Strong reference, may be NULL. Only valid if not on C stack */
90+ _Py_CODEUNIT * instr_ptr ; /* Instruction currently executing (or about to begin) */
91+ _PyStackRef * stackpointer ;
8692 /* Locals and stack */
8793 _PyStackRef localsplus [1 ];
8894} _PyInterpreterFrame ;
8995
96+
97+ typedef union _PyVMFrame {
98+ struct _PyFrameCore core ;
99+ _PyInterpreterFrame iframe ;
100+ } _PyVMFrame ;
101+
90102#define _PyInterpreterFrame_LASTI (IF ) \
91103 ((int)((IF)->instr_ptr - _PyFrame_GetBytecode((IF))))
92104
@@ -200,7 +212,7 @@ _PyFrame_Initialize(
200212 PyThreadState * tstate , _PyInterpreterFrame * frame , _PyStackRef func ,
201213 PyObject * locals , PyCodeObject * code , int null_locals_from , _PyInterpreterFrame * previous )
202214{
203- frame -> previous = previous ;
215+ frame -> previous = ( _PyVMFrame * ) previous ;
204216 frame -> f_funcobj = func ;
205217 frame -> f_executable = PyStackRef_FromPyObjectNew (code );
206218 PyFunctionObject * func_obj = (PyFunctionObject * )PyStackRef_AsPyObjectBorrow (func );
@@ -264,23 +276,32 @@ _PyFrame_SetStackPointer(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer)
264276 * Frames owned by a generator are always complete.
265277 */
266278static inline bool
267- _PyFrame_IsIncomplete ( _PyInterpreterFrame * frame )
279+ _PyVMFrame_IsIncomplete ( _PyVMFrame * frame )
268280{
269- if (frame -> owner >= FRAME_OWNED_BY_INTERPRETER ) {
281+ if (frame -> core . owner >= FRAME_OWNED_BY_INTERPRETER ) {
270282 return true;
271283 }
272- return frame -> owner != FRAME_OWNED_BY_GENERATOR &&
273- frame -> instr_ptr < _PyFrame_GetBytecode (frame ) +
274- _PyFrame_GetCode (frame )-> _co_firsttraceable ;
284+ if (frame -> core .owner == FRAME_OWNED_BY_GENERATOR ) {
285+ return false;
286+ }
287+ _PyInterpreterFrame * iframe = & frame -> iframe ;
288+ return iframe -> instr_ptr < _PyFrame_GetBytecode (iframe ) +
289+ _PyFrame_GetCode (iframe )-> _co_firsttraceable ;
290+ }
291+
292+ static inline bool
293+ _PyFrame_IsIncomplete (_PyInterpreterFrame * frame )
294+ {
295+ return _PyVMFrame_IsIncomplete ((_PyVMFrame * )frame );
275296}
276297
277298static inline _PyInterpreterFrame *
278- _PyFrame_GetFirstComplete (_PyInterpreterFrame * frame )
299+ _PyFrame_GetFirstComplete (_PyVMFrame * frame )
279300{
280- while (frame && _PyFrame_IsIncomplete (frame )) {
281- frame = frame -> previous ;
301+ while (frame && _PyVMFrame_IsIncomplete (frame )) {
302+ frame = frame -> core . previous ;
282303 }
283- return frame ;
304+ return ( _PyInterpreterFrame * ) frame ;
284305}
285306
286307static inline _PyInterpreterFrame *
@@ -376,7 +397,7 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int
376397 _PyInterpreterFrame * frame = (_PyInterpreterFrame * )tstate -> datastack_top ;
377398 tstate -> datastack_top += code -> co_framesize ;
378399 assert (tstate -> datastack_top < tstate -> datastack_limit );
379- frame -> previous = previous ;
400+ frame -> previous = ( _PyVMFrame * ) previous ;
380401 frame -> f_funcobj = PyStackRef_None ;
381402 frame -> f_executable = PyStackRef_FromPyObjectNew (code );
382403#ifdef Py_DEBUG
0 commit comments