Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/python3.12/internal/pycore_frame.h
$ cat -n /usr/include/python3.12/internal/pycore_frame.h 1 #ifndef Py_INTERNAL_FRAME_H 2 #define Py_INTERNAL_FRAME_H 3 #ifdef __cplusplus 4 extern "C" { 5 #endif 6 7 #include
8 #include
9 #include "pycore_code.h" // STATS 10 11 /* See Objects/frame_layout.md for an explanation of the frame stack 12 * including explanation of the PyFrameObject and _PyInterpreterFrame 13 * structs. */ 14 15 16 struct _frame { 17 PyObject_HEAD 18 PyFrameObject *f_back; /* previous frame, or NULL */ 19 struct _PyInterpreterFrame *f_frame; /* points to the frame data */ 20 PyObject *f_trace; /* Trace function */ 21 int f_lineno; /* Current line number. Only valid if non-zero */ 22 char f_trace_lines; /* Emit per-line trace events? */ 23 char f_trace_opcodes; /* Emit per-opcode trace events? */ 24 char f_fast_as_locals; /* Have the fast locals of this frame been converted to a dict? */ 25 /* The frame data, if this frame object owns the frame */ 26 PyObject *_f_frame_data[1]; 27 }; 28 29 extern PyFrameObject* _PyFrame_New_NoTrack(PyCodeObject *code); 30 31 32 /* other API */ 33 34 typedef enum _framestate { 35 FRAME_CREATED = -2, 36 FRAME_SUSPENDED = -1, 37 FRAME_EXECUTING = 0, 38 FRAME_COMPLETED = 1, 39 FRAME_CLEARED = 4 40 } PyFrameState; 41 42 #define FRAME_STATE_FINISHED(S) ((S) >= FRAME_COMPLETED) 43 44 enum _frameowner { 45 FRAME_OWNED_BY_THREAD = 0, 46 FRAME_OWNED_BY_GENERATOR = 1, 47 FRAME_OWNED_BY_FRAME_OBJECT = 2, 48 FRAME_OWNED_BY_CSTACK = 3, 49 }; 50 51 typedef struct _PyInterpreterFrame { 52 PyCodeObject *f_code; /* Strong reference */ 53 struct _PyInterpreterFrame *previous; 54 PyObject *f_funcobj; /* Strong reference. Only valid if not on C stack */ 55 PyObject *f_globals; /* Borrowed reference. Only valid if not on C stack */ 56 PyObject *f_builtins; /* Borrowed reference. Only valid if not on C stack */ 57 PyObject *f_locals; /* Strong reference, may be NULL. Only valid if not on C stack */ 58 PyFrameObject *frame_obj; /* Strong reference, may be NULL. Only valid if not on C stack */ 59 // NOTE: This is not necessarily the last instruction started in the given 60 // frame. Rather, it is the code unit *prior to* the *next* instruction. For 61 // example, it may be an inline CACHE entry, an instruction we just jumped 62 // over, or (in the case of a newly-created frame) a totally invalid value: 63 _Py_CODEUNIT *prev_instr; 64 int stacktop; /* Offset of TOS from localsplus */ 65 /* The return_offset determines where a `RETURN` should go in the caller, 66 * relative to `prev_instr`. 67 * It is only meaningful to the callee, 68 * so it needs to be set in any CALL (to a Python function) 69 * or SEND (to a coroutine or generator). 70 * If there is no callee, then it is meaningless. */ 71 uint16_t return_offset; 72 char owner; 73 /* Locals and stack */ 74 PyObject *localsplus[1]; 75 } _PyInterpreterFrame; 76 77 #define _PyInterpreterFrame_LASTI(IF) \ 78 ((int)((IF)->prev_instr - _PyCode_CODE((IF)->f_code))) 79 80 static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) { 81 return f->localsplus + f->f_code->co_nlocalsplus; 82 } 83 84 static inline PyObject *_PyFrame_StackPeek(_PyInterpreterFrame *f) { 85 assert(f->stacktop > f->f_code->co_nlocalsplus); 86 assert(f->localsplus[f->stacktop-1] != NULL); 87 return f->localsplus[f->stacktop-1]; 88 } 89 90 static inline PyObject *_PyFrame_StackPop(_PyInterpreterFrame *f) { 91 assert(f->stacktop > f->f_code->co_nlocalsplus); 92 f->stacktop--; 93 return f->localsplus[f->stacktop]; 94 } 95 96 static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) { 97 f->localsplus[f->stacktop] = value; 98 f->stacktop++; 99 } 100 101 #define FRAME_SPECIALS_SIZE ((int)((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *))) 102 103 static inline int 104 _PyFrame_NumSlotsForCodeObject(PyCodeObject *code) 105 { 106 /* This function needs to remain in sync with the calculation of 107 * co_framesize in Tools/build/deepfreeze.py */ 108 assert(code->co_framesize >= FRAME_SPECIALS_SIZE); 109 return code->co_framesize - FRAME_SPECIALS_SIZE; 110 } 111 112 void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest); 113 114 /* Consumes reference to func and locals. 115 Does not initialize frame->previous, which happens 116 when frame is linked into the frame stack. 117 */ 118 static inline void 119 _PyFrame_Initialize( 120 _PyInterpreterFrame *frame, PyFunctionObject *func, 121 PyObject *locals, PyCodeObject *code, int null_locals_from) 122 { 123 frame->f_funcobj = (PyObject *)func; 124 frame->f_code = (PyCodeObject *)Py_NewRef(code); 125 frame->f_builtins = func->func_builtins; 126 frame->f_globals = func->func_globals; 127 frame->f_locals = locals; 128 frame->stacktop = code->co_nlocalsplus; 129 frame->frame_obj = NULL; 130 frame->prev_instr = _PyCode_CODE(code) - 1; 131 frame->return_offset = 0; 132 frame->owner = FRAME_OWNED_BY_THREAD; 133 134 for (int i = null_locals_from; i < code->co_nlocalsplus; i++) { 135 frame->localsplus[i] = NULL; 136 } 137 } 138 139 /* Gets the pointer to the locals array 140 * that precedes this frame. 141 */ 142 static inline PyObject** 143 _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame) 144 { 145 return frame->localsplus; 146 } 147 148 /* Fetches the stack pointer, and sets stacktop to -1. 149 Having stacktop <= 0 ensures that invalid 150 values are not visible to the cycle GC. 151 We choose -1 rather than 0 to assist debugging. */ 152 static inline PyObject** 153 _PyFrame_GetStackPointer(_PyInterpreterFrame *frame) 154 { 155 PyObject **sp = frame->localsplus + frame->stacktop; 156 frame->stacktop = -1; 157 return sp; 158 } 159 160 static inline void 161 _PyFrame_SetStackPointer(_PyInterpreterFrame *frame, PyObject **stack_pointer) 162 { 163 frame->stacktop = (int)(stack_pointer - frame->localsplus); 164 } 165 166 /* Determine whether a frame is incomplete. 167 * A frame is incomplete if it is part way through 168 * creating cell objects or a generator or coroutine. 169 * 170 * Frames on the frame stack are incomplete until the 171 * first RESUME instruction. 172 * Frames owned by a generator are always complete. 173 */ 174 static inline bool 175 _PyFrame_IsIncomplete(_PyInterpreterFrame *frame) 176 { 177 return frame->owner != FRAME_OWNED_BY_GENERATOR && 178 frame->prev_instr < _PyCode_CODE(frame->f_code) + frame->f_code->_co_firsttraceable; 179 } 180 181 static inline _PyInterpreterFrame * 182 _PyFrame_GetFirstComplete(_PyInterpreterFrame *frame) 183 { 184 while (frame && _PyFrame_IsIncomplete(frame)) { 185 frame = frame->previous; 186 } 187 return frame; 188 } 189 190 static inline _PyInterpreterFrame * 191 _PyThreadState_GetFrame(PyThreadState *tstate) 192 { 193 return _PyFrame_GetFirstComplete(tstate->cframe->current_frame); 194 } 195 196 /* For use by _PyFrame_GetFrameObject 197 Do not call directly. */ 198 PyFrameObject * 199 _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame); 200 201 /* Gets the PyFrameObject for this frame, lazily 202 * creating it if necessary. 203 * Returns a borrowed referennce */ 204 static inline PyFrameObject * 205 _PyFrame_GetFrameObject(_PyInterpreterFrame *frame) 206 { 207 208 assert(!_PyFrame_IsIncomplete(frame)); 209 PyFrameObject *res = frame->frame_obj; 210 if (res != NULL) { 211 return res; 212 } 213 return _PyFrame_MakeAndSetFrameObject(frame); 214 } 215 216 /* Clears all references in the frame. 217 * If take is non-zero, then the _PyInterpreterFrame frame 218 * may be transferred to the frame object it references 219 * instead of being cleared. Either way 220 * the caller no longer owns the references 221 * in the frame. 222 * take should be set to 1 for heap allocated 223 * frames like the ones in generators and coroutines. 224 */ 225 void 226 _PyFrame_ClearExceptCode(_PyInterpreterFrame * frame); 227 228 int 229 _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg); 230 231 PyObject * 232 _PyFrame_GetLocals(_PyInterpreterFrame *frame, int include_hidden); 233 234 int 235 _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame); 236 237 void 238 _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear); 239 240 static inline bool 241 _PyThreadState_HasStackSpace(PyThreadState *tstate, int size) 242 { 243 assert( 244 (tstate->datastack_top == NULL && tstate->datastack_limit == NULL) 245 || 246 (tstate->datastack_top != NULL && tstate->datastack_limit != NULL) 247 ); 248 return tstate->datastack_top != NULL && 249 size < tstate->datastack_limit - tstate->datastack_top; 250 } 251 252 extern _PyInterpreterFrame * 253 _PyThreadState_PushFrame(PyThreadState *tstate, size_t size); 254 255 void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); 256 257 /* Pushes a frame without checking for space. 258 * Must be guarded by _PyThreadState_HasStackSpace() 259 * Consumes reference to func. */ 260 static inline _PyInterpreterFrame * 261 _PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func, int null_locals_from) 262 { 263 CALL_STAT_INC(frames_pushed); 264 PyCodeObject *code = (PyCodeObject *)func->func_code; 265 _PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)tstate->datastack_top; 266 tstate->datastack_top += code->co_framesize; 267 assert(tstate->datastack_top < tstate->datastack_limit); 268 _PyFrame_Initialize(new_frame, func, NULL, code, null_locals_from); 269 return new_frame; 270 } 271 272 static inline 273 PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame) 274 { 275 assert(frame->owner == FRAME_OWNED_BY_GENERATOR); 276 size_t offset_in_gen = offsetof(PyGenObject, gi_iframe); 277 return (PyGenObject *)(((char *)frame) - offset_in_gen); 278 } 279 280 #ifdef __cplusplus 281 } 282 #endif 283 #endif /* !Py_INTERNAL_FRAME_H */
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2025 MyWebUniversity.com ™