| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | #ifndef Py_INTERNAL_FRAME_H
 | 
					
						
							|  |  |  | #define Py_INTERNAL_FRAME_H
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-05 03:30:26 -08:00
										 |  |  | #include <stdbool.h>
 | 
					
						
							| 
									
										
										
										
											2022-03-22 12:57:19 +00:00
										 |  |  | #include <stddef.h>
 | 
					
						
							| 
									
										
										
										
											2022-01-05 03:30:26 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-03 16:55:55 +10:00
										 |  |  | /* Starting in CPython 3.11, CPython separates the frame state between the
 | 
					
						
							|  |  |  |  * full frame objects exposed by the Python and C runtime state introspection | 
					
						
							|  |  |  |  * APIs, and internal lighter weight interpreter frames, which are simple C | 
					
						
							|  |  |  |  * structures owned by either the interpreter eval loop (while executing | 
					
						
							|  |  |  |  * ordinary functions), by a generator or coroutine object (for frames that | 
					
						
							|  |  |  |  * are able to be suspended), or by their corresponding full frame object (if | 
					
						
							|  |  |  |  * a state instrospection API has been invoked and the full frame object has | 
					
						
							|  |  |  |  * taken responsibility for the lifecycle of the interpreter frame). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This split storage eliminates a lot of allocation and deallocation of full | 
					
						
							|  |  |  |  * Python objects during code execution, providing a significant speed gain | 
					
						
							|  |  |  |  * over the previous approach of using full Python objects for both | 
					
						
							|  |  |  |  * introspection and code execution. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Struct names: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   * PyFrameObject: the full Python frame object | 
					
						
							|  |  |  |  *   * _PyInterpreterFrame: the lightweight frame struct used by the eval loop | 
					
						
							|  |  |  |  *   * _PyCFrame: a struct that lives on the C stack and allows Python level | 
					
						
							|  |  |  |  *     recursive evaluation to be decoupled from recursive C level invocation | 
					
						
							|  |  |  |  *     of the bytecode eval loop | 
					
						
							|  |  |  |  *       * See pystate.h for more details on this struct | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Field naming conventions: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   * full frame object fields have an "f_*" (or "_f_*") prefix | 
					
						
							|  |  |  |  *   * new interpreter frame fields have no prefix | 
					
						
							|  |  |  |  *   * Several interpreter frame fields have the "f_*" prefix as a result of | 
					
						
							|  |  |  |  *     trying to keep diffs as small as was feasible when splitting the original | 
					
						
							|  |  |  |  *     frame struct definition in two. The following are all interpreter frame | 
					
						
							|  |  |  |  *     fields, NOT full frame object fields: | 
					
						
							|  |  |  |  *     * f_func | 
					
						
							|  |  |  |  *     * f_globals | 
					
						
							|  |  |  |  *     * f_builtins | 
					
						
							|  |  |  |  *     * f_locals | 
					
						
							|  |  |  |  *     * f_code | 
					
						
							|  |  |  |  *     * f_lasti | 
					
						
							|  |  |  |  *     * f_state | 
					
						
							|  |  |  |  *   * Renaming those fields was considered but ultimately deemed too disruptive | 
					
						
							|  |  |  |  *     to key third party projects that were trying to keep up with the Python | 
					
						
							|  |  |  |  *     3.11 code evaluation changes during the alpha release cycle | 
					
						
							|  |  |  |  *     (see bpo-44800 for details) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Naming conventions for local variables, function parameters and fields in other structs: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   * "frame" and "f" may refer to either full frame objects or interpreter frames | 
					
						
							|  |  |  |  *     * the context of use or the field naming conventions usually make the | 
					
						
							|  |  |  |  *       type being referenced unambiguous in code reviews | 
					
						
							|  |  |  |  *   * the following alternative names are used when more clarity is needed: | 
					
						
							|  |  |  |  *     * full frame objects: "frame_obj" (and variants like "frameobj" or "fobj") | 
					
						
							|  |  |  |  *     * interpreter frame structs: "frame_data" or "iframe" | 
					
						
							|  |  |  |  *   * "current frame" should NOT be abbreviated as "cframe", as the latter now | 
					
						
							|  |  |  |  *     typically refers to _PyCFrame structs | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Function/macro parameter types: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   * "PyFrame_*" functions and other public C API functions that relate to | 
					
						
							|  |  |  |  *     frames accept full frame object pointers | 
					
						
							|  |  |  |  *   * "_PyFrame_*" functions and other private C API functions that relate to | 
					
						
							|  |  |  |  *     frames accept either full frame object or interpreter frame pointers. | 
					
						
							|  |  |  |  *     Check the specific function signatures for details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Function return types: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   * Public C API functions will only ever return full frame object pointers | 
					
						
							|  |  |  |  *   * Private C API functions with an underscore prefix may return interpreter | 
					
						
							|  |  |  |  *     frame pointers instead. Check the specific function signatures for details. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 12:53:19 +01:00
										 |  |  | struct _frame { | 
					
						
							|  |  |  |     PyObject_HEAD | 
					
						
							|  |  |  |     PyFrameObject *f_back;      /* previous frame, or NULL */ | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  |     struct _PyInterpreterFrame *f_frame; /* points to the frame data */ | 
					
						
							| 
									
										
										
										
											2022-02-25 12:53:19 +01:00
										 |  |  |     PyObject *f_trace;          /* Trace function */ | 
					
						
							|  |  |  |     int f_lineno;               /* Current line number. Only valid if non-zero */ | 
					
						
							|  |  |  |     char f_trace_lines;         /* Emit per-line trace events? */ | 
					
						
							|  |  |  |     char f_trace_opcodes;       /* Emit per-opcode trace events? */ | 
					
						
							| 
									
										
										
										
											2022-03-25 12:57:50 +00:00
										 |  |  |     char f_fast_as_locals;      /* Have the fast locals of this frame been converted to a dict? */ | 
					
						
							| 
									
										
										
										
											2022-02-25 12:53:19 +01:00
										 |  |  |     /* The frame data, if this frame object owns the frame */ | 
					
						
							|  |  |  |     PyObject *_f_frame_data[1]; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:07:14 +01:00
										 |  |  | extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* other API */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 12:57:19 +00:00
										 |  |  | typedef enum _framestate { | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  |     FRAME_CREATED = -2, | 
					
						
							|  |  |  |     FRAME_SUSPENDED = -1, | 
					
						
							|  |  |  |     FRAME_EXECUTING = 0, | 
					
						
							| 
									
										
										
										
											2022-03-22 12:57:19 +00:00
										 |  |  |     FRAME_COMPLETED = 1, | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  |     FRAME_CLEARED = 4 | 
					
						
							| 
									
										
										
										
											2022-03-22 12:57:19 +00:00
										 |  |  | } PyFrameState; | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 12:57:19 +00:00
										 |  |  | enum _frameowner { | 
					
						
							|  |  |  |     FRAME_OWNED_BY_THREAD = 0, | 
					
						
							|  |  |  |     FRAME_OWNED_BY_GENERATOR = 1, | 
					
						
							|  |  |  |     FRAME_OWNED_BY_FRAME_OBJECT = 2 | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-01 12:09:36 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |     frame->f_lasti refers to the index of the last instruction, | 
					
						
							|  |  |  |     unless it's -1 in which case next_instr should be first_instr. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | typedef struct _PyInterpreterFrame { | 
					
						
							| 
									
										
										
										
											2021-11-23 09:53:24 +00:00
										 |  |  |     PyFunctionObject *f_func; /* Strong reference */ | 
					
						
							|  |  |  |     PyObject *f_globals; /* Borrowed reference */ | 
					
						
							|  |  |  |     PyObject *f_builtins; /* Borrowed reference */ | 
					
						
							|  |  |  |     PyObject *f_locals; /* Strong reference, may be NULL */ | 
					
						
							|  |  |  |     PyCodeObject *f_code; /* Strong reference */ | 
					
						
							|  |  |  |     PyFrameObject *frame_obj; /* Strong reference, may be NULL */ | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  |     struct _PyInterpreterFrame *previous; | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  |     int f_lasti;       /* Last instruction if called */ | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     int stacktop;     /* Offset of TOS from localsplus  */ | 
					
						
							| 
									
										
										
										
											2022-02-28 16:03:57 +01:00
										 |  |  |     bool is_entry;  // Whether this is the "root" frame for the current _PyCFrame.
 | 
					
						
							| 
									
										
										
										
											2022-03-22 12:57:19 +00:00
										 |  |  |     char owner; | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     PyObject *localsplus[1]; | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | } _PyInterpreterFrame; | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) { | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     return f->localsplus + f->f_code->co_nlocalsplus; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | static inline PyObject *_PyFrame_StackPeek(_PyInterpreterFrame *f) { | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     assert(f->stacktop > f->f_code->co_nlocalsplus); | 
					
						
							| 
									
										
										
										
											2021-12-15 10:30:09 +00:00
										 |  |  |     assert(f->localsplus[f->stacktop-1] != NULL); | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     return f->localsplus[f->stacktop-1]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | static inline PyObject *_PyFrame_StackPop(_PyInterpreterFrame *f) { | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     assert(f->stacktop > f->f_code->co_nlocalsplus); | 
					
						
							|  |  |  |     f->stacktop--; | 
					
						
							|  |  |  |     return f->localsplus[f->stacktop]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) { | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     f->localsplus[f->stacktop] = value; | 
					
						
							|  |  |  |     f->stacktop++; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | #define FRAME_SPECIALS_SIZE ((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *))
 | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest); | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-03 18:36:28 +00:00
										 |  |  | /* Consumes reference to func */ | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | static inline void | 
					
						
							|  |  |  | _PyFrame_InitializeSpecials( | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  |     _PyInterpreterFrame *frame, PyFunctionObject *func, | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  |     PyObject *locals, int nlocalsplus) | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-11-23 09:53:24 +00:00
										 |  |  |     frame->f_func = func; | 
					
						
							|  |  |  |     frame->f_code = (PyCodeObject *)Py_NewRef(func->func_code); | 
					
						
							|  |  |  |     frame->f_builtins = func->func_builtins; | 
					
						
							|  |  |  |     frame->f_globals = func->func_globals; | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  |     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->f_lasti = -1; | 
					
						
							| 
									
										
										
										
											2022-01-05 03:30:26 -08:00
										 |  |  |     frame->is_entry = false; | 
					
						
							| 
									
										
										
										
											2022-03-22 12:57:19 +00:00
										 |  |  |     frame->owner = FRAME_OWNED_BY_THREAD; | 
					
						
							| 
									
										
										
										
											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** | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame) | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  |     return frame->localsplus; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline PyObject** | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyFrame_GetStackPointer(_PyInterpreterFrame *frame) | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     return frame->localsplus+frame->stacktop; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyFrame_SetStackPointer(_PyInterpreterFrame *frame, PyObject **stack_pointer) | 
					
						
							| 
									
										
										
										
											2021-08-25 13:44:20 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     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 * | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame); | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Gets the PyFrameObject for this frame, lazily
 | 
					
						
							|  |  |  |  * creating it if necessary. | 
					
						
							|  |  |  |  * Returns a borrowed referennce */ | 
					
						
							|  |  |  | static inline PyFrameObject * | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyFrame_GetFrameObject(_PyInterpreterFrame *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.
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  |  * If take is non-zero, then the _PyInterpreterFrame frame | 
					
						
							| 
									
										
										
										
											2021-10-06 20:32:38 +02:00
										 |  |  |  * may be transferred to the frame object it references | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-11-29 12:34:59 +00:00
										 |  |  | void | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyFrame_Clear(_PyInterpreterFrame * frame); | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg); | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame); | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear); | 
					
						
							| 
									
										
										
										
											2021-07-26 11:22:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | extern _PyInterpreterFrame * | 
					
						
							| 
									
										
										
										
											2021-10-28 16:14:59 +01:00
										 |  |  | _PyThreadState_BumpFramePointerSlow(PyThreadState *tstate, size_t size); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | static inline _PyInterpreterFrame * | 
					
						
							| 
									
										
										
										
											2021-10-28 16:14:59 +01:00
										 |  |  | _PyThreadState_BumpFramePointer(PyThreadState *tstate, size_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     PyObject **base = tstate->datastack_top; | 
					
						
							| 
									
										
										
										
											2021-12-28 09:49:48 -08:00
										 |  |  |     if (base) { | 
					
						
							|  |  |  |         PyObject **top = base + size; | 
					
						
							|  |  |  |         assert(tstate->datastack_limit); | 
					
						
							|  |  |  |         if (top < tstate->datastack_limit) { | 
					
						
							|  |  |  |             tstate->datastack_top = top; | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  |             return (_PyInterpreterFrame *)base; | 
					
						
							| 
									
										
										
										
											2021-12-28 09:49:48 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-10-28 16:14:59 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     return _PyThreadState_BumpFramePointerSlow(tstate, size); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-03 18:36:28 +00:00
										 |  |  | /* Consume reference to func */ | 
					
						
							| 
									
										
										
										
											2022-02-25 16:22:00 +01:00
										 |  |  | _PyInterpreterFrame * | 
					
						
							| 
									
										
										
										
											2022-01-28 12:42:30 +00:00
										 |  |  | _PyFrame_Push(PyThreadState *tstate, PyFunctionObject *func); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-22 12:57:19 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static inline | 
					
						
							|  |  |  | PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(frame->owner == FRAME_OWNED_BY_GENERATOR); | 
					
						
							|  |  |  |     size_t offset_in_gen = offsetof(PyGenObject, gi_iframe); | 
					
						
							|  |  |  |     return (PyGenObject *)(((char *)frame) - offset_in_gen); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-21 10:57:35 +01:00
										 |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif /* !Py_INTERNAL_FRAME_H */
 |