@@ -63,7 +63,7 @@ typedef struct _PyInterpreterFrame {
63
63
PyObject * f_locals ; /* Strong reference, may be NULL. Only valid if not on C stack */
64
64
PyFrameObject * frame_obj ; /* Strong reference, may be NULL. Only valid if not on C stack */
65
65
_Py_CODEUNIT * instr_ptr ; /* Instruction currently executing (or about to begin) */
66
- int stacktop ; /* Offset of TOS from localsplus */
66
+ PyObject * * stackpointer ;
67
67
uint16_t return_offset ; /* Only relevant during a function call */
68
68
char owner ;
69
69
/* Locals and stack */
@@ -83,20 +83,20 @@ static inline PyObject **_PyFrame_Stackbase(_PyInterpreterFrame *f) {
83
83
}
84
84
85
85
static inline PyObject * _PyFrame_StackPeek (_PyInterpreterFrame * f ) {
86
- assert (f -> stacktop > _PyFrame_GetCode (f )-> co_nlocalsplus );
87
- assert (f -> localsplus [ f -> stacktop - 1 ] != NULL );
88
- return f -> localsplus [ f -> stacktop - 1 ];
86
+ assert (f -> stackpointer > f -> localsplus + _PyFrame_GetCode (f )-> co_nlocalsplus );
87
+ assert (f -> stackpointer [ -1 ] != NULL );
88
+ return f -> stackpointer [ -1 ];
89
89
}
90
90
91
91
static inline PyObject * _PyFrame_StackPop (_PyInterpreterFrame * f ) {
92
- assert (f -> stacktop > _PyFrame_GetCode (f )-> co_nlocalsplus );
93
- f -> stacktop -- ;
94
- return f -> localsplus [ f -> stacktop ] ;
92
+ assert (f -> stackpointer > f -> localsplus + _PyFrame_GetCode (f )-> co_nlocalsplus );
93
+ f -> stackpointer -- ;
94
+ return * f -> stackpointer ;
95
95
}
96
96
97
97
static inline void _PyFrame_StackPush (_PyInterpreterFrame * f , PyObject * value ) {
98
- f -> localsplus [ f -> stacktop ] = value ;
99
- f -> stacktop ++ ;
98
+ * f -> stackpointer = value ;
99
+ f -> stackpointer ++ ;
100
100
}
101
101
102
102
#define FRAME_SPECIALS_SIZE ((int)((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *)))
@@ -112,9 +112,12 @@ _PyFrame_NumSlotsForCodeObject(PyCodeObject *code)
112
112
113
113
static inline void _PyFrame_Copy (_PyInterpreterFrame * src , _PyInterpreterFrame * dest )
114
114
{
115
- assert (src -> stacktop >= _PyFrame_GetCode (src )-> co_nlocalsplus );
116
115
* dest = * src ;
117
- for (int i = 1 ; i < src -> stacktop ; i ++ ) {
116
+ assert (src -> stackpointer != NULL );
117
+ int stacktop = (int )(src -> stackpointer - src -> localsplus );
118
+ assert (stacktop >= _PyFrame_GetCode (src )-> co_nlocalsplus );
119
+ dest -> stackpointer = dest -> localsplus + stacktop ;
120
+ for (int i = 1 ; i < stacktop ; i ++ ) {
118
121
dest -> localsplus [i ] = src -> localsplus [i ];
119
122
}
120
123
// Don't leave a dangling pointer to the old frame when creating generators
@@ -136,7 +139,7 @@ _PyFrame_Initialize(
136
139
frame -> f_builtins = func -> func_builtins ;
137
140
frame -> f_globals = func -> func_globals ;
138
141
frame -> f_locals = locals ;
139
- frame -> stacktop = code -> co_nlocalsplus ;
142
+ frame -> stackpointer = frame -> localsplus + code -> co_nlocalsplus ;
140
143
frame -> frame_obj = NULL ;
141
144
frame -> instr_ptr = _PyCode_CODE (code );
142
145
frame -> return_offset = 0 ;
@@ -156,24 +159,23 @@ _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame)
156
159
return frame -> localsplus ;
157
160
}
158
161
159
- /* Fetches the stack pointer, and sets stacktop to -1.
160
- Having stacktop <= 0 ensures that invalid
161
- values are not visible to the cycle GC.
162
- We choose -1 rather than 0 to assist debugging. */
162
+ /* Fetches the stack pointer, and sets stackpointer to NULL.
163
+ Having stackpointer == NULL ensures that invalid
164
+ values are not visible to the cycle GC. */
163
165
static inline PyObject * *
164
166
_PyFrame_GetStackPointer (_PyInterpreterFrame * frame )
165
167
{
166
- assert (frame -> stacktop >= 0 );
167
- PyObject * * sp = frame -> localsplus + frame -> stacktop ;
168
- frame -> stacktop = -1 ;
168
+ assert (frame -> stackpointer != NULL );
169
+ PyObject * * sp = frame -> stackpointer ;
170
+ frame -> stackpointer = NULL ;
169
171
return sp ;
170
172
}
171
173
172
174
static inline void
173
175
_PyFrame_SetStackPointer (_PyInterpreterFrame * frame , PyObject * * stack_pointer )
174
176
{
175
- assert (frame -> stacktop == -1 );
176
- frame -> stacktop = ( int )( stack_pointer - frame -> localsplus ) ;
177
+ assert (frame -> stackpointer == NULL );
178
+ frame -> stackpointer = stack_pointer ;
177
179
}
178
180
179
181
/* Determine whether a frame is incomplete.
@@ -301,7 +303,8 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int
301
303
frame -> f_globals = NULL ;
302
304
#endif
303
305
frame -> f_locals = NULL ;
304
- frame -> stacktop = code -> co_nlocalsplus + stackdepth ;
306
+ assert (stackdepth <= code -> co_stacksize );
307
+ frame -> stackpointer = frame -> localsplus + code -> co_nlocalsplus + stackdepth ;
305
308
frame -> frame_obj = NULL ;
306
309
frame -> instr_ptr = _PyCode_CODE (code );
307
310
frame -> owner = FRAME_OWNED_BY_THREAD ;
0 commit comments