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