@@ -68,7 +68,7 @@ typedef struct _PyInterpreterFrame {
6868 PyObject * f_locals ; /* Strong reference, may be NULL. Only valid if not on C stack */
6969 PyFrameObject * frame_obj ; /* Strong reference, may be NULL. Only valid if not on C stack */
7070 _Py_CODEUNIT * instr_ptr ; /* Instruction currently executing (or about to begin) */
71- int stacktop ; /* Offset of TOS from localsplus */
71+ _PyStackRef * stackpointer ;
7272 uint16_t return_offset ; /* Only relevant during a function call */
7373 char owner ;
7474 /* Locals and stack */
@@ -88,20 +88,20 @@ static inline _PyStackRef *_PyFrame_Stackbase(_PyInterpreterFrame *f) {
8888}
8989
9090static 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 ];
9494}
9595
9696static 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 ;
100100}
101101
102102static inline void _PyFrame_StackPush (_PyInterpreterFrame * f , _PyStackRef value ) {
103- f -> localsplus [ f -> stacktop ] = value ;
104- f -> stacktop ++ ;
103+ * f -> stackpointer = value ;
104+ f -> stackpointer ++ ;
105105}
106106
107107#define FRAME_SPECIALS_SIZE ((int)((sizeof(_PyInterpreterFrame)-1)/sizeof(PyObject *)))
@@ -117,9 +117,12 @@ _PyFrame_NumSlotsForCodeObject(PyCodeObject *code)
117117
118118static inline void _PyFrame_Copy (_PyInterpreterFrame * src , _PyInterpreterFrame * dest )
119119{
120- assert (src -> stacktop >= _PyFrame_GetCode (src )-> co_nlocalsplus );
121120 * 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 ++ ) {
123126 dest -> localsplus [i ] = src -> localsplus [i ];
124127 }
125128 // Don't leave a dangling pointer to the old frame when creating generators
@@ -141,7 +144,7 @@ _PyFrame_Initialize(
141144 frame -> f_builtins = func -> func_builtins ;
142145 frame -> f_globals = func -> func_globals ;
143146 frame -> f_locals = locals ;
144- frame -> stacktop = code -> co_nlocalsplus ;
147+ frame -> stackpointer = frame -> localsplus + code -> co_nlocalsplus ;
145148 frame -> frame_obj = NULL ;
146149 frame -> instr_ptr = _PyCode_CODE (code );
147150 frame -> return_offset = 0 ;
@@ -161,22 +164,23 @@ _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame)
161164 return frame -> localsplus ;
162165}
163166
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. */
168170static inline _PyStackRef *
169171_PyFrame_GetStackPointer (_PyInterpreterFrame * frame )
170172{
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 ;
173176 return sp ;
174177}
175178
176179static inline void
177180_PyFrame_SetStackPointer (_PyInterpreterFrame * frame , _PyStackRef * stack_pointer )
178181{
179- frame -> stacktop = (int )(stack_pointer - frame -> localsplus );
182+ assert (frame -> stackpointer == NULL );
183+ frame -> stackpointer = stack_pointer ;
180184}
181185
182186/* Determine whether a frame is incomplete.
@@ -304,7 +308,8 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int
304308 frame -> f_globals = NULL ;
305309#endif
306310 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 ;
308313 frame -> frame_obj = NULL ;
309314 frame -> instr_ptr = _PyCode_CODE (code );
310315 frame -> owner = FRAME_OWNED_BY_THREAD ;
0 commit comments