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