| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | #ifndef Py_INTERNAL_FRAME_H
 | 
					
						
							|  |  |  | #define Py_INTERNAL_FRAME_H
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | /* These values are chosen so that the inline functions below all
 | 
					
						
							|  |  |  |  * compare f_state to zero. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | enum _framestate { | 
					
						
							|  |  |  |     FRAME_CREATED = -2, | 
					
						
							|  |  |  |     FRAME_SUSPENDED = -1, | 
					
						
							|  |  |  |     FRAME_EXECUTING = 0, | 
					
						
							|  |  |  |     FRAME_RETURNED = 1, | 
					
						
							|  |  |  |     FRAME_UNWINDING = 2, | 
					
						
							|  |  |  |     FRAME_RAISED = 3, | 
					
						
							|  |  |  |     FRAME_CLEARED = 4 | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | typedef signed char PyFrameState; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct _interpreter_frame { | 
					
						
							|  |  |  |     PyObject *f_globals; | 
					
						
							|  |  |  |     PyObject *f_builtins; | 
					
						
							|  |  |  |     PyObject *f_locals; | 
					
						
							|  |  |  |     PyCodeObject *f_code; | 
					
						
							|  |  |  |     PyFrameObject *frame_obj; | 
					
						
							|  |  |  |     /* Borrowed reference to a generator, or NULL */ | 
					
						
							|  |  |  |     PyObject *generator; | 
					
						
							|  |  |  |     struct _interpreter_frame *previous; | 
					
						
							|  |  |  |     int f_lasti;       /* Last instruction if called */ | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     int stacktop;     /* Offset of TOS from localsplus  */ | 
					
						
							|  |  |  |     PyFrameState f_state;  /* What state the frame is in */ | 
					
						
							|  |  |  |     PyObject *localsplus[1]; | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | } InterpreterFrame; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline int _PyFrame_IsRunnable(InterpreterFrame *f) { | 
					
						
							|  |  |  |     return f->f_state < FRAME_EXECUTING; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline int _PyFrame_IsExecuting(InterpreterFrame *f) { | 
					
						
							|  |  |  |     return f->f_state == FRAME_EXECUTING; | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | static inline int _PyFrameHasCompleted(InterpreterFrame *f) { | 
					
						
							|  |  |  |     return f->f_state > FRAME_EXECUTING; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  | static inline PyObject **_PyFrame_Stackbase(InterpreterFrame *f) { | 
					
						
							|  |  |  |     return f->localsplus + f->f_code->co_nlocalsplus; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline PyObject *_PyFrame_StackPeek(InterpreterFrame *f) { | 
					
						
							|  |  |  |     assert(f->stacktop > f->f_code->co_nlocalsplus); | 
					
						
							|  |  |  |     return f->localsplus[f->stacktop-1]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline PyObject *_PyFrame_StackPop(InterpreterFrame *f) { | 
					
						
							|  |  |  |     assert(f->stacktop > f->f_code->co_nlocalsplus); | 
					
						
							|  |  |  |     f->stacktop--; | 
					
						
							|  |  |  |     return f->localsplus[f->stacktop]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void _PyFrame_StackPush(InterpreterFrame *f, PyObject *value) { | 
					
						
							|  |  |  |     f->localsplus[f->stacktop] = value; | 
					
						
							|  |  |  |     f->stacktop++; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | #define FRAME_SPECIALS_SIZE ((sizeof(InterpreterFrame)-1)/sizeof(PyObject *))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | InterpreterFrame * | 
					
						
							|  |  |  | _PyInterpreterFrame_HeapAlloc(PyFrameConstructor *con, PyObject *locals); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | _PyFrame_InitializeSpecials( | 
					
						
							|  |  |  |     InterpreterFrame *frame, PyFrameConstructor *con, | 
					
						
							|  |  |  |     PyObject *locals, int nlocalsplus) | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  |     frame->f_code = (PyCodeObject *)Py_NewRef(con->fc_code); | 
					
						
							|  |  |  |     frame->f_builtins = Py_NewRef(con->fc_builtins); | 
					
						
							|  |  |  |     frame->f_globals = Py_NewRef(con->fc_globals); | 
					
						
							|  |  |  |     frame->f_locals = Py_XNewRef(locals); | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     frame->stacktop = nlocalsplus; | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  |     frame->frame_obj = NULL; | 
					
						
							|  |  |  |     frame->generator = NULL; | 
					
						
							|  |  |  |     frame->f_lasti = -1; | 
					
						
							|  |  |  |     frame->f_state = FRAME_CREATED; | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | /* Gets the pointer to the locals array
 | 
					
						
							|  |  |  |  * that precedes this frame. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline PyObject** | 
					
						
							|  |  |  | _PyFrame_GetLocalsArray(InterpreterFrame *frame) | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     return frame->localsplus; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline PyObject** | 
					
						
							|  |  |  | _PyFrame_GetStackPointer(InterpreterFrame *frame) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return frame->localsplus+frame->stacktop; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | _PyFrame_SetStackPointer(InterpreterFrame *frame, PyObject **stack_pointer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     frame->stacktop = (int)(stack_pointer - frame->localsplus); | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | /* For use by _PyFrame_GetFrameObject
 | 
					
						
							|  |  |  |   Do not call directly. */ | 
					
						
							|  |  |  | PyFrameObject * | 
					
						
							|  |  |  | _PyFrame_MakeAndSetFrameObject(InterpreterFrame *frame); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Gets the PyFrameObject for this frame, lazily
 | 
					
						
							|  |  |  |  * creating it if necessary. | 
					
						
							|  |  |  |  * Returns a borrowed referennce */ | 
					
						
							|  |  |  | static inline PyFrameObject * | 
					
						
							|  |  |  | _PyFrame_GetFrameObject(InterpreterFrame *frame) | 
					
						
							| 
									
										
										
										
											2021-06-18 11:00:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  |     PyFrameObject *res =  frame->frame_obj; | 
					
						
							|  |  |  |     if (res != NULL) { | 
					
						
							|  |  |  |         return res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return _PyFrame_MakeAndSetFrameObject(frame); | 
					
						
							| 
									
										
										
										
											2021-06-18 11:00:29 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | /* Clears all references in the frame.
 | 
					
						
							|  |  |  |  * If take is non-zero, then the InterpreterFrame frame | 
					
						
							|  |  |  |  * may be transfered to the frame object it references | 
					
						
							|  |  |  |  * instead of being cleared. Either way | 
					
						
							|  |  |  |  * the caller no longer owns the references | 
					
						
							|  |  |  |  * in the frame. | 
					
						
							|  |  |  |  * take should  be set to 1 for heap allocated | 
					
						
							|  |  |  |  * frames like the ones in generators and coroutines. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _PyFrame_Clear(InterpreterFrame * frame, int take); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _PyFrame_Traverse(InterpreterFrame *frame, visitproc visit, void *arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | _PyFrame_FastToLocalsWithError(InterpreterFrame *frame); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | _PyFrame_LocalsToFast(InterpreterFrame *frame, int clear); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | InterpreterFrame *_PyThreadState_PushFrame( | 
					
						
							|  |  |  |     PyThreadState *tstate, PyFrameConstructor *con, PyObject *locals); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void _PyThreadState_PopFrame(PyThreadState *tstate, InterpreterFrame *frame); | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif /* !Py_INTERNAL_FRAME_H */
 |