Branch data Line data Source code
1 : : #ifndef Py_INTERNAL_FRAME_H 2 : : #define Py_INTERNAL_FRAME_H 3 : : #ifdef __cplusplus 4 : : extern "C" { 5 : : #endif 6 : : 7 : : #include <stdbool.h> 8 : : #include <stddef.h> 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 : : enum _frameowner { 43 : : FRAME_OWNED_BY_THREAD = 0, 44 : : FRAME_OWNED_BY_GENERATOR = 1, 45 : : FRAME_OWNED_BY_FRAME_OBJECT = 2 46 : : }; 47 : : 48 : : typedef struct _PyInterpreterFrame { 49 : : /* "Specials" section */ 50 : : PyFunctionObject *f_func; /* Strong reference */ 51 : : PyObject *f_globals; /* Borrowed reference */ 52 : : PyObject *f_builtins; /* Borrowed reference */ 53 : : PyObject *f_locals; /* Strong reference, may be NULL */ 54 : : PyCodeObject *f_code; /* Strong reference */ 55 : : PyFrameObject *frame_obj; /* Strong reference, may be NULL */ 56 : : /* Linkage section */ 57 : : struct _PyInterpreterFrame *previous; 58 : : // NOTE: This is not necessarily the last instruction started in the given 59 : : // frame. Rather, it is the code unit *prior to* the *next* instruction. For 60 : : // example, it may be an inline CACHE entry, an instruction we just jumped 61 : : // over, or (in the case of a newly-created frame) a totally invalid value: 62 : : _Py_CODEUNIT *prev_instr; 63 : : int stacktop; /* Offset of TOS from localsplus */ 64 : : bool is_entry; // Whether this is the "root" frame for the current _PyCFrame. 65 : : char owner; 66 : : /* Locals and stack */ 67 : : PyObject *localsplus[1]; 68 : : } _PyInterpreterFrame; 69 : : 70 : : #define _PyInterpreterFrame_LASTI(IF) \ 71 : : ((int)((IF)->prev_instr - _PyCode_CODE((IF)->f_code))) 72 : : 73 : 5973257 : static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) { 74 : 5973257 : return f->localsplus + f->f_code->co_nlocalsplus; 75 : : } 76 : : 77 : 14882 : static inline PyObject *_PyFrame_StackPeek(_PyInterpreterFrame *f) { 78 : : assert(f->stacktop > f->f_code->co_nlocalsplus); 79 : : assert(f->localsplus[f->stacktop-1] != NULL); 80 : 14882 : return f->localsplus[f->stacktop-1]; 81 : : } 82 : : 83 : 1269 : static inline PyObject *_PyFrame_StackPop(_PyInterpreterFrame *f) { 84 : : assert(f->stacktop > f->f_code->co_nlocalsplus); 85 : 1269 : f->stacktop--; 86 : 1269 : return f->localsplus[f->stacktop]; 87 : : } 88 : : 89 : 260669836 : static inline void _PyFrame_StackPush(_PyInterpreterFrame *f, PyObject *value) { 90 : 260669836 : f->localsplus[f->stacktop] = value; 91 : 260669836 : f->stacktop++; 92 : 260669836 : } 93 : : 94 : : #define FRAME_SPECIALS_SIZE ((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *)) 95 : : 96 : : void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest); 97 : : 98 : : /* Consumes reference to func and locals */ 99 : : static inline void 100 : 269958431 : _PyFrame_InitializeSpecials( 101 : : _PyInterpreterFrame *frame, PyFunctionObject *func, 102 : : PyObject *locals, PyCodeObject *code) 103 : : { 104 : 269958431 : frame->f_func = func; 105 : 269958431 : frame->f_code = (PyCodeObject *)Py_NewRef(code); 106 : 269958431 : frame->f_builtins = func->func_builtins; 107 : 269958431 : frame->f_globals = func->func_globals; 108 : 269958431 : frame->f_locals = locals; 109 : 269958431 : frame->stacktop = code->co_nlocalsplus; 110 : 269958431 : frame->frame_obj = NULL; 111 : 269958431 : frame->prev_instr = _PyCode_CODE(code) - 1; 112 : 269958431 : frame->is_entry = false; 113 : 269958431 : frame->owner = FRAME_OWNED_BY_THREAD; 114 : 269958431 : } 115 : : 116 : : /* Gets the pointer to the locals array 117 : : * that precedes this frame. 118 : : */ 119 : : static inline PyObject** 120 : 21520229 : _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame) 121 : : { 122 : 21520229 : return frame->localsplus; 123 : : } 124 : : 125 : : static inline PyObject** 126 : 537084082 : _PyFrame_GetStackPointer(_PyInterpreterFrame *frame) 127 : : { 128 : 537084082 : return frame->localsplus+frame->stacktop; 129 : : } 130 : : 131 : : static inline void 132 : 537083794 : _PyFrame_SetStackPointer(_PyInterpreterFrame *frame, PyObject **stack_pointer) 133 : : { 134 : 537083794 : frame->stacktop = (int)(stack_pointer - frame->localsplus); 135 : 537083794 : } 136 : : 137 : : /* Determine whether a frame is incomplete. 138 : : * A frame is incomplete if it is part way through 139 : : * creating cell objects or a generator or coroutine. 140 : : * 141 : : * Frames on the frame stack are incomplete until the 142 : : * first RESUME instruction. 143 : : * Frames owned by a generator are always complete. 144 : : */ 145 : : static inline bool 146 : 1291588 : _PyFrame_IsIncomplete(_PyInterpreterFrame *frame) 147 : : { 148 [ + + ]: 2571556 : return frame->owner != FRAME_OWNED_BY_GENERATOR && 149 [ + + ]: 1279968 : frame->prev_instr < _PyCode_CODE(frame->f_code) + frame->f_code->_co_firsttraceable; 150 : : } 151 : : 152 : : /* For use by _PyFrame_GetFrameObject 153 : : Do not call directly. */ 154 : : PyFrameObject * 155 : : _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame); 156 : : 157 : : /* Gets the PyFrameObject for this frame, lazily 158 : : * creating it if necessary. 159 : : * Returns a borrowed referennce */ 160 : : static inline PyFrameObject * 161 : 14020927 : _PyFrame_GetFrameObject(_PyInterpreterFrame *frame) 162 : : { 163 : : 164 : : assert(!_PyFrame_IsIncomplete(frame)); 165 : 14020927 : PyFrameObject *res = frame->frame_obj; 166 [ + + ]: 14020927 : if (res != NULL) { 167 : 8837186 : return res; 168 : : } 169 : 5183741 : return _PyFrame_MakeAndSetFrameObject(frame); 170 : : } 171 : : 172 : : /* Clears all references in the frame. 173 : : * If take is non-zero, then the _PyInterpreterFrame frame 174 : : * may be transferred to the frame object it references 175 : : * instead of being cleared. Either way 176 : : * the caller no longer owns the references 177 : : * in the frame. 178 : : * take should be set to 1 for heap allocated 179 : : * frames like the ones in generators and coroutines. 180 : : */ 181 : : void 182 : : _PyFrame_Clear(_PyInterpreterFrame * frame); 183 : : 184 : : int 185 : : _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg); 186 : : 187 : : int 188 : : _PyFrame_FastToLocalsWithError(_PyInterpreterFrame *frame); 189 : : 190 : : void 191 : : _PyFrame_LocalsToFast(_PyInterpreterFrame *frame, int clear); 192 : : 193 : : 194 : : static inline bool 195 : 150392152 : _PyThreadState_HasStackSpace(PyThreadState *tstate, int size) 196 : : { 197 : 150392152 : return tstate->datastack_top + size < tstate->datastack_limit; 198 : : } 199 : : 200 : : extern _PyInterpreterFrame * 201 : : _PyThreadState_PushFrame(PyThreadState *tstate, size_t size); 202 : : 203 : : void _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame *frame); 204 : : 205 : : /* Pushes a frame without checking for space. 206 : : * Must be guarded by _PyThreadState_HasStackSpace() 207 : : * Consumes reference to func. */ 208 : : static inline _PyInterpreterFrame * 209 : 150388199 : _PyFrame_PushUnchecked(PyThreadState *tstate, PyFunctionObject *func) 210 : : { 211 : : CALL_STAT_INC(frames_pushed); 212 : 150388199 : PyCodeObject *code = (PyCodeObject *)func->func_code; 213 : 150388199 : _PyInterpreterFrame *new_frame = (_PyInterpreterFrame *)tstate->datastack_top; 214 : 150388199 : tstate->datastack_top += code->co_framesize; 215 : : assert(tstate->datastack_top < tstate->datastack_limit); 216 : 150388199 : _PyFrame_InitializeSpecials(new_frame, func, NULL, code); 217 : 150388199 : return new_frame; 218 : : } 219 : : 220 : : int _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame); 221 : : 222 : : static inline 223 : 45071231 : PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame) 224 : : { 225 : : assert(frame->owner == FRAME_OWNED_BY_GENERATOR); 226 : 45071231 : size_t offset_in_gen = offsetof(PyGenObject, gi_iframe); 227 : 45071231 : return (PyGenObject *)(((char *)frame) - offset_in_gen); 228 : : } 229 : : 230 : : #ifdef __cplusplus 231 : : } 232 : : #endif 233 : : #endif /* !Py_INTERNAL_FRAME_H */