@@ -68,7 +68,7 @@ typedef struct _PyInterpreterFrame {
68
68
PyObject * f_locals ; /* Strong reference, may be NULL. Only valid if not on C stack */
69
69
PyFrameObject * frame_obj ; /* Strong reference, may be NULL. Only valid if not on C stack */
70
70
_Py_CODEUNIT * instr_ptr ; /* Instruction currently executing (or about to begin) */
71
- int stacktop ; /* Offset of TOS from localsplus */
71
+ _PyStackRef * stackpointer ;
72
72
uint16_t return_offset ; /* Only relevant during a function call */
73
73
char owner ;
74
74
/* Locals and stack */
@@ -88,20 +88,20 @@ static inline _PyStackRef *_PyFrame_Stackbase(_PyInterpreterFrame *f) {
88
88
}
89
89
90
90
static inline _PyStackRef _PyFrame_StackPeek (_PyInterpreterFrame * f ) {
91
- assert (f -> stacktop > _PyFrame_GetCode (f )-> co_nlocalsplus );
92
- assert (!PyStackRef_IsNull (f -> localsplus [ f -> stacktop - 1 ]));
93
- return f -> localsplus [ f -> stacktop - 1 ];
91
+ assert (f -> stackpointer > f -> localsplus + _PyFrame_GetCode (f )-> co_nlocalsplus );
92
+ assert (!PyStackRef_IsNull (f -> stackpointer [ -1 ]));
93
+ return f -> stackpointer [ -1 ];
94
94
}
95
95
96
96
static inline _PyStackRef _PyFrame_StackPop (_PyInterpreterFrame * f ) {
97
- assert (f -> stacktop > _PyFrame_GetCode (f )-> co_nlocalsplus );
98
- f -> stacktop -- ;
99
- return f -> localsplus [ f -> stacktop ] ;
97
+ assert (f -> stackpointer > f -> localsplus + _PyFrame_GetCode (f )-> co_nlocalsplus );
98
+ f -> stackpointer -- ;
99
+ return * f -> stackpointer ;
100
100
}
101
101
102
102
static inline void _PyFrame_StackPush (_PyInterpreterFrame * f , _PyStackRef value ) {
103
- f -> localsplus [ f -> stacktop ] = value ;
104
- f -> stacktop ++ ;
103
+ * f -> stackpointer = value ;
104
+ f -> stackpointer ++ ;
105
105
}
106
106
107
107
#define FRAME_SPECIALS_SIZE ((int)((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *)))
@@ -117,9 +117,12 @@ _PyFrame_NumSlotsForCodeObject(PyCodeObject *code)
117
117
118
118
static inline void _PyFrame_Copy (_PyInterpreterFrame * src , _PyInterpreterFrame * dest )
119
119
{
120
- assert (src -> stacktop >= _PyFrame_GetCode (src )-> co_nlocalsplus );
121
120
* dest = * src ;
122
- for (int i = 1 ; i < src -> stacktop ; i ++ ) {
121
+ assert (src -> stackpointer != NULL );
122
+ int stacktop = (int )(src -> stackpointer - src -> localsplus );
123
+ assert (stacktop >= _PyFrame_GetCode (src )-> co_nlocalsplus );
124
+ dest -> stackpointer = dest -> localsplus + stacktop ;
125
+ for (int i = 1 ; i < stacktop ; i ++ ) {
123
126
dest -> localsplus [i ] = src -> localsplus [i ];
124
127
}
125
128
// Don't leave a dangling pointer to the old frame when creating generators
@@ -141,7 +144,7 @@ _PyFrame_Initialize(
141
144
frame -> f_builtins = func -> func_builtins ;
142
145
frame -> f_globals = func -> func_globals ;
143
146
frame -> f_locals = locals ;
144
- frame -> stacktop = code -> co_nlocalsplus ;
147
+ frame -> stackpointer = frame -> localsplus + code -> co_nlocalsplus ;
145
148
frame -> frame_obj = NULL ;
146
149
frame -> instr_ptr = _PyCode_CODE (code );
147
150
frame -> return_offset = 0 ;
@@ -161,22 +164,23 @@ _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame)
161
164
return frame -> localsplus ;
162
165
}
163
166
164
- /* Fetches the stack pointer, and sets stacktop to -1.
165
- Having stacktop <= 0 ensures that invalid
166
- values are not visible to the cycle GC.
167
- We choose -1 rather than 0 to assist debugging. */
167
+ /* Fetches the stack pointer, and sets stackpointer to NULL.
168
+ Having stackpointer == NULL ensures that invalid
169
+ values are not visible to the cycle GC. */
168
170
static inline _PyStackRef *
169
171
_PyFrame_GetStackPointer (_PyInterpreterFrame * frame )
170
172
{
171
- _PyStackRef * sp = frame -> localsplus + frame -> stacktop ;
172
- frame -> stacktop = -1 ;
173
+ assert (frame -> stackpointer != NULL );
174
+ _PyStackRef * sp = frame -> stackpointer ;
175
+ frame -> stackpointer = NULL ;
173
176
return sp ;
174
177
}
175
178
176
179
static inline void
177
180
_PyFrame_SetStackPointer (_PyInterpreterFrame * frame , _PyStackRef * stack_pointer )
178
181
{
179
- frame -> stacktop = (int )(stack_pointer - frame -> localsplus );
182
+ assert (frame -> stackpointer == NULL );
183
+ frame -> stackpointer = stack_pointer ;
180
184
}
181
185
182
186
/* Determine whether a frame is incomplete.
@@ -304,7 +308,8 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int
304
308
frame -> f_globals = NULL ;
305
309
#endif
306
310
frame -> f_locals = NULL ;
307
- frame -> stacktop = code -> co_nlocalsplus + stackdepth ;
311
+ assert (stackdepth <= code -> co_stacksize );
312
+ frame -> stackpointer = frame -> localsplus + code -> co_nlocalsplus + stackdepth ;
308
313
frame -> frame_obj = NULL ;
309
314
frame -> instr_ptr = _PyCode_CODE (code );
310
315
frame -> owner = FRAME_OWNED_BY_THREAD ;
0 commit comments