@@ -8,11 +8,6 @@ extern "C" {
88# error "this header requires Py_BUILD_CORE define"
99#endif
1010
11- #include <stdbool.h>
12- #include <stddef.h> // offsetof()
13- #include "pycore_code.h" // STATS
14- #include "pycore_stackref.h" // _PyStackRef
15-
1611/* See InternalDocs/frames.md for an explanation of the frame stack
1712 * including explanation of the PyFrameObject and _PyInterpreterFrame
1813 * structs. */
@@ -52,360 +47,6 @@ typedef enum _framestate {
5247#define FRAME_STATE_SUSPENDED (S ) ((S) == FRAME_SUSPENDED || (S) == FRAME_SUSPENDED_YIELD_FROM)
5348#define FRAME_STATE_FINISHED (S ) ((S) >= FRAME_COMPLETED)
5449
55- enum _frameowner {
56- FRAME_OWNED_BY_THREAD = 0 ,
57- FRAME_OWNED_BY_GENERATOR = 1 ,
58- FRAME_OWNED_BY_FRAME_OBJECT = 2 ,
59- FRAME_OWNED_BY_INTERPRETER = 3 ,
60- FRAME_OWNED_BY_CSTACK = 4 ,
61- };
62-
63- typedef struct _PyInterpreterFrame {
64- _PyStackRef f_executable ; /* Deferred or strong reference (code object or None) */
65- struct _PyInterpreterFrame * previous ;
66- _PyStackRef f_funcobj ; /* Deferred or strong reference. Only valid if not on C stack */
67- PyObject * f_globals ; /* Borrowed reference. Only valid if not on C stack */
68- PyObject * f_builtins ; /* Borrowed reference. Only valid if not on C stack */
69- PyObject * f_locals ; /* Strong reference, may be NULL. Only valid if not on C stack */
70- PyFrameObject * frame_obj ; /* Strong reference, may be NULL. Only valid if not on C stack */
71- _Py_CODEUNIT * instr_ptr ; /* Instruction currently executing (or about to begin) */
72- _PyStackRef * stackpointer ;
73- #ifdef Py_GIL_DISABLED
74- /* Index of thread-local bytecode containing instr_ptr. */
75- int32_t tlbc_index ;
76- #endif
77- uint16_t return_offset ; /* Only relevant during a function call */
78- char owner ;
79- #ifdef Py_DEBUG
80- uint8_t visited :1 ;
81- uint8_t lltrace :7 ;
82- #else
83- uint8_t visited ;
84- #endif
85- /* Locals and stack */
86- _PyStackRef localsplus [1 ];
87- } _PyInterpreterFrame ;
88-
89- #define _PyInterpreterFrame_LASTI (IF ) \
90- ((int)((IF)->instr_ptr - _PyFrame_GetBytecode((IF))))
91-
92- static inline PyCodeObject * _PyFrame_GetCode (_PyInterpreterFrame * f ) {
93- PyObject * executable = PyStackRef_AsPyObjectBorrow (f -> f_executable );
94- assert (PyCode_Check (executable ));
95- return (PyCodeObject * )executable ;
96- }
97-
98- static inline _Py_CODEUNIT *
99- _PyFrame_GetBytecode (_PyInterpreterFrame * f )
100- {
101- #ifdef Py_GIL_DISABLED
102- PyCodeObject * co = _PyFrame_GetCode (f );
103- _PyCodeArray * tlbc = _PyCode_GetTLBCArray (co );
104- assert (f -> tlbc_index >= 0 && f -> tlbc_index < tlbc -> size );
105- return (_Py_CODEUNIT * )tlbc -> entries [f -> tlbc_index ];
106- #else
107- return _PyCode_CODE (_PyFrame_GetCode (f ));
108- #endif
109- }
110-
111- static inline PyFunctionObject * _PyFrame_GetFunction (_PyInterpreterFrame * f ) {
112- PyObject * func = PyStackRef_AsPyObjectBorrow (f -> f_funcobj );
113- assert (PyFunction_Check (func ));
114- return (PyFunctionObject * )func ;
115- }
116-
117- static inline _PyStackRef * _PyFrame_Stackbase (_PyInterpreterFrame * f ) {
118- return (f -> localsplus + _PyFrame_GetCode (f )-> co_nlocalsplus );
119- }
120-
121- static inline _PyStackRef _PyFrame_StackPeek (_PyInterpreterFrame * f ) {
122- assert (f -> stackpointer > f -> localsplus + _PyFrame_GetCode (f )-> co_nlocalsplus );
123- assert (!PyStackRef_IsNull (f -> stackpointer [-1 ]));
124- return f -> stackpointer [-1 ];
125- }
126-
127- static inline _PyStackRef _PyFrame_StackPop (_PyInterpreterFrame * f ) {
128- assert (f -> stackpointer > f -> localsplus + _PyFrame_GetCode (f )-> co_nlocalsplus );
129- f -> stackpointer -- ;
130- return * f -> stackpointer ;
131- }
132-
133- static inline void _PyFrame_StackPush (_PyInterpreterFrame * f , _PyStackRef value ) {
134- * f -> stackpointer = value ;
135- f -> stackpointer ++ ;
136- }
137-
138- #define FRAME_SPECIALS_SIZE ((int)((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *)))
139-
140- static inline int
141- _PyFrame_NumSlotsForCodeObject (PyCodeObject * code )
142- {
143- /* This function needs to remain in sync with the calculation of
144- * co_framesize in Tools/build/deepfreeze.py */
145- assert (code -> co_framesize >= FRAME_SPECIALS_SIZE );
146- return code -> co_framesize - FRAME_SPECIALS_SIZE ;
147- }
148-
149- static inline void _PyFrame_Copy (_PyInterpreterFrame * src , _PyInterpreterFrame * dest )
150- {
151- dest -> f_executable = PyStackRef_MakeHeapSafe (src -> f_executable );
152- // Don't leave a dangling pointer to the old frame when creating generators
153- // and coroutines:
154- dest -> previous = NULL ;
155- dest -> f_funcobj = PyStackRef_MakeHeapSafe (src -> f_funcobj );
156- dest -> f_globals = src -> f_globals ;
157- dest -> f_builtins = src -> f_builtins ;
158- dest -> f_locals = src -> f_locals ;
159- dest -> frame_obj = src -> frame_obj ;
160- dest -> instr_ptr = src -> instr_ptr ;
161- #ifdef Py_GIL_DISABLED
162- dest -> tlbc_index = src -> tlbc_index ;
163- #endif
164- assert (src -> stackpointer != NULL );
165- int stacktop = (int )(src -> stackpointer - src -> localsplus );
166- assert (stacktop >= 0 );
167- dest -> stackpointer = dest -> localsplus + stacktop ;
168- for (int i = 0 ; i < stacktop ; i ++ ) {
169- dest -> localsplus [i ] = PyStackRef_MakeHeapSafe (src -> localsplus [i ]);
170- }
171- }
172-
173- #ifdef Py_GIL_DISABLED
174- static inline void
175- _PyFrame_InitializeTLBC (PyThreadState * tstate , _PyInterpreterFrame * frame ,
176- PyCodeObject * code )
177- {
178- _Py_CODEUNIT * tlbc = _PyCode_GetTLBCFast (tstate , code );
179- if (tlbc == NULL ) {
180- // No thread-local bytecode exists for this thread yet; use the main
181- // thread's copy, deferring thread-local bytecode creation to the
182- // execution of RESUME.
183- frame -> instr_ptr = _PyCode_CODE (code );
184- frame -> tlbc_index = 0 ;
185- }
186- else {
187- frame -> instr_ptr = tlbc ;
188- frame -> tlbc_index = ((_PyThreadStateImpl * )tstate )-> tlbc_index ;
189- }
190- }
191- #endif
192-
193- /* Consumes reference to func and locals.
194- Does not initialize frame->previous, which happens
195- when frame is linked into the frame stack.
196- */
197- static inline void
198- _PyFrame_Initialize (
199- PyThreadState * tstate , _PyInterpreterFrame * frame , _PyStackRef func ,
200- PyObject * locals , PyCodeObject * code , int null_locals_from , _PyInterpreterFrame * previous )
201- {
202- frame -> previous = previous ;
203- frame -> f_funcobj = func ;
204- frame -> f_executable = PyStackRef_FromPyObjectNew (code );
205- PyFunctionObject * func_obj = (PyFunctionObject * )PyStackRef_AsPyObjectBorrow (func );
206- frame -> f_builtins = func_obj -> func_builtins ;
207- frame -> f_globals = func_obj -> func_globals ;
208- frame -> f_locals = locals ;
209- frame -> stackpointer = frame -> localsplus + code -> co_nlocalsplus ;
210- frame -> frame_obj = NULL ;
211- #ifdef Py_GIL_DISABLED
212- _PyFrame_InitializeTLBC (tstate , frame , code );
213- #else
214- (void )tstate ;
215- frame -> instr_ptr = _PyCode_CODE (code );
216- #endif
217- frame -> return_offset = 0 ;
218- frame -> owner = FRAME_OWNED_BY_THREAD ;
219- frame -> visited = 0 ;
220- #ifdef Py_DEBUG
221- frame -> lltrace = 0 ;
222- #endif
223-
224- for (int i = null_locals_from ; i < code -> co_nlocalsplus ; i ++ ) {
225- frame -> localsplus [i ] = PyStackRef_NULL ;
226- }
227- }
228-
229- /* Gets the pointer to the locals array
230- * that precedes this frame.
231- */
232- static inline _PyStackRef *
233- _PyFrame_GetLocalsArray (_PyInterpreterFrame * frame )
234- {
235- return frame -> localsplus ;
236- }
237-
238- /* Fetches the stack pointer, and sets stackpointer to NULL.
239- Having stackpointer == NULL ensures that invalid
240- values are not visible to the cycle GC. */
241- static inline _PyStackRef *
242- _PyFrame_GetStackPointer (_PyInterpreterFrame * frame )
243- {
244- assert (frame -> stackpointer != NULL );
245- _PyStackRef * sp = frame -> stackpointer ;
246- frame -> stackpointer = NULL ;
247- return sp ;
248- }
249-
250- static inline void
251- _PyFrame_SetStackPointer (_PyInterpreterFrame * frame , _PyStackRef * stack_pointer )
252- {
253- assert (frame -> stackpointer == NULL );
254- frame -> stackpointer = stack_pointer ;
255- }
256-
257- /* Determine whether a frame is incomplete.
258- * A frame is incomplete if it is part way through
259- * creating cell objects or a generator or coroutine.
260- *
261- * Frames on the frame stack are incomplete until the
262- * first RESUME instruction.
263- * Frames owned by a generator are always complete.
264- */
265- static inline bool
266- _PyFrame_IsIncomplete (_PyInterpreterFrame * frame )
267- {
268- if (frame -> owner >= FRAME_OWNED_BY_INTERPRETER ) {
269- return true;
270- }
271- return frame -> owner != FRAME_OWNED_BY_GENERATOR &&
272- frame -> instr_ptr < _PyFrame_GetBytecode (frame ) +
273- _PyFrame_GetCode (frame )-> _co_firsttraceable ;
274- }
275-
276- static inline _PyInterpreterFrame *
277- _PyFrame_GetFirstComplete (_PyInterpreterFrame * frame )
278- {
279- while (frame && _PyFrame_IsIncomplete (frame )) {
280- frame = frame -> previous ;
281- }
282- return frame ;
283- }
284-
285- static inline _PyInterpreterFrame *
286- _PyThreadState_GetFrame (PyThreadState * tstate )
287- {
288- return _PyFrame_GetFirstComplete (tstate -> current_frame );
289- }
290-
291- /* For use by _PyFrame_GetFrameObject
292- Do not call directly. */
293- PyFrameObject *
294- _PyFrame_MakeAndSetFrameObject (_PyInterpreterFrame * frame );
295-
296- /* Gets the PyFrameObject for this frame, lazily
297- * creating it if necessary.
298- * Returns a borrowed reference */
299- static inline PyFrameObject *
300- _PyFrame_GetFrameObject (_PyInterpreterFrame * frame )
301- {
302-
303- assert (!_PyFrame_IsIncomplete (frame ));
304- PyFrameObject * res = frame -> frame_obj ;
305- if (res != NULL ) {
306- return res ;
307- }
308- return _PyFrame_MakeAndSetFrameObject (frame );
309- }
310-
311- void
312- _PyFrame_ClearLocals (_PyInterpreterFrame * frame );
313-
314- /* Clears all references in the frame.
315- * If take is non-zero, then the _PyInterpreterFrame frame
316- * may be transferred to the frame object it references
317- * instead of being cleared. Either way
318- * the caller no longer owns the references
319- * in the frame.
320- * take should be set to 1 for heap allocated
321- * frames like the ones in generators and coroutines.
322- */
323- void
324- _PyFrame_ClearExceptCode (_PyInterpreterFrame * frame );
325-
326- int
327- _PyFrame_Traverse (_PyInterpreterFrame * frame , visitproc visit , void * arg );
328-
329- bool
330- _PyFrame_HasHiddenLocals (_PyInterpreterFrame * frame );
331-
332- PyObject *
333- _PyFrame_GetLocals (_PyInterpreterFrame * frame );
334-
335- static inline bool
336- _PyThreadState_HasStackSpace (PyThreadState * tstate , int size )
337- {
338- assert (
339- (tstate -> datastack_top == NULL && tstate -> datastack_limit == NULL )
340- ||
341- (tstate -> datastack_top != NULL && tstate -> datastack_limit != NULL )
342- );
343- return tstate -> datastack_top != NULL &&
344- size < tstate -> datastack_limit - tstate -> datastack_top ;
345- }
346-
347- extern _PyInterpreterFrame *
348- _PyThreadState_PushFrame (PyThreadState * tstate , size_t size );
349-
350- PyAPI_FUNC (void ) _PyThreadState_PopFrame (PyThreadState * tstate , _PyInterpreterFrame * frame );
351-
352- /* Pushes a frame without checking for space.
353- * Must be guarded by _PyThreadState_HasStackSpace()
354- * Consumes reference to func. */
355- static inline _PyInterpreterFrame *
356- _PyFrame_PushUnchecked (PyThreadState * tstate , _PyStackRef func , int null_locals_from , _PyInterpreterFrame * previous )
357- {
358- CALL_STAT_INC (frames_pushed );
359- PyFunctionObject * func_obj = (PyFunctionObject * )PyStackRef_AsPyObjectBorrow (func );
360- PyCodeObject * code = (PyCodeObject * )func_obj -> func_code ;
361- _PyInterpreterFrame * new_frame = (_PyInterpreterFrame * )tstate -> datastack_top ;
362- tstate -> datastack_top += code -> co_framesize ;
363- assert (tstate -> datastack_top < tstate -> datastack_limit );
364- _PyFrame_Initialize (tstate , new_frame , func , NULL , code , null_locals_from ,
365- previous );
366- return new_frame ;
367- }
368-
369- /* Pushes a trampoline frame without checking for space.
370- * Must be guarded by _PyThreadState_HasStackSpace() */
371- static inline _PyInterpreterFrame *
372- _PyFrame_PushTrampolineUnchecked (PyThreadState * tstate , PyCodeObject * code , int stackdepth , _PyInterpreterFrame * previous )
373- {
374- CALL_STAT_INC (frames_pushed );
375- _PyInterpreterFrame * frame = (_PyInterpreterFrame * )tstate -> datastack_top ;
376- tstate -> datastack_top += code -> co_framesize ;
377- assert (tstate -> datastack_top < tstate -> datastack_limit );
378- frame -> previous = previous ;
379- frame -> f_funcobj = PyStackRef_None ;
380- frame -> f_executable = PyStackRef_FromPyObjectNew (code );
381- #ifdef Py_DEBUG
382- frame -> f_builtins = NULL ;
383- frame -> f_globals = NULL ;
384- #endif
385- frame -> f_locals = NULL ;
386- assert (stackdepth <= code -> co_stacksize );
387- frame -> stackpointer = frame -> localsplus + code -> co_nlocalsplus + stackdepth ;
388- frame -> frame_obj = NULL ;
389- #ifdef Py_GIL_DISABLED
390- _PyFrame_InitializeTLBC (tstate , frame , code );
391- #else
392- frame -> instr_ptr = _PyCode_CODE (code );
393- #endif
394- frame -> owner = FRAME_OWNED_BY_THREAD ;
395- frame -> visited = 0 ;
396- #ifdef Py_DEBUG
397- frame -> lltrace = 0 ;
398- #endif
399- frame -> return_offset = 0 ;
400- return frame ;
401- }
402-
403- PyAPI_FUNC (_PyInterpreterFrame * )
404- _PyEvalFramePushAndInit (PyThreadState * tstate , _PyStackRef func ,
405- PyObject * locals , _PyStackRef const * args ,
406- size_t argcount , PyObject * kwnames ,
407- _PyInterpreterFrame * previous );
408-
40950#ifdef __cplusplus
41051}
41152#endif
0 commit comments