@@ -152,6 +152,7 @@ static inline void _PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *
152152 // visited is GC bookkeeping for the current stack walk, not frame state.
153153 dest -> visited = 0 ;
154154#ifdef Py_DEBUG
155+ dest -> stackpointer_valid = src -> stackpointer_valid ;
155156 dest -> lltrace = src -> lltrace ;
156157#endif
157158 for (int i = 0 ; i < stacktop ; i ++ ) {
@@ -207,6 +208,7 @@ _PyFrame_Initialize(
207208 frame -> owner = FRAME_OWNED_BY_THREAD ;
208209 frame -> visited = 0 ;
209210#ifdef Py_DEBUG
211+ frame -> stackpointer_valid = 1 ;
210212 frame -> lltrace = 0 ;
211213#endif
212214
@@ -230,26 +232,51 @@ _PyFrame_GetLocalsArray(_PyInterpreterFrame *frame)
230232static inline _PyStackRef *
231233_PyFrame_GetStackPointer (_PyInterpreterFrame * frame )
232234{
235+ return frame -> stackpointer ;
236+ }
237+
238+ static inline void
239+ _PyFrame_SetStackPointer (_PyInterpreterFrame * frame , _PyStackRef * stack_pointer )
240+ {
241+ frame -> stackpointer = stack_pointer ;
242+ }
243+
244+ static inline void
245+ _PyFrame_StackPointerValidate (_PyInterpreterFrame * frame )
246+ {
247+ #ifdef Py_DEBUG
248+ /* Avoid bloating the JIT code */
233249#ifndef _Py_JIT
234- assert (frame -> stackpointer != NULL );
250+ assert (frame -> stackpointer_valid == 0 );
235251#endif
236- _PyStackRef * sp = frame -> stackpointer ;
237- #ifndef NDEBUG
238- frame -> stackpointer = NULL ;
252+ frame -> stackpointer_valid = 1 ;
239253#endif
240- return sp ;
241254}
242255
243256static inline void
244- _PyFrame_SetStackPointer (_PyInterpreterFrame * frame , _PyStackRef * stack_pointer )
257+ _PyFrame_StackPointerInvalidate (_PyInterpreterFrame * frame )
245258{
259+ #ifdef Py_DEBUG
246260/* Avoid bloating the JIT code */
247261#ifndef _Py_JIT
248- assert (frame -> stackpointer == NULL );
262+ assert (frame -> stackpointer_valid == 1 );
263+ #endif
264+ frame -> stackpointer_valid = 0 ;
249265#endif
250- frame -> stackpointer = stack_pointer ;
251266}
252267
268+ static inline void
269+ _PyFrame_StackAssertInvalid (_PyInterpreterFrame * frame )
270+ {
271+ #ifdef Py_DEBUG
272+ /* Avoid bloating the JIT code */
273+ #ifndef _Py_JIT
274+ assert (frame -> stackpointer_valid == 0 );
275+ #endif
276+ #endif
277+ }
278+
279+
253280/* Determine whether a frame is incomplete.
254281 * A frame is incomplete if it is part way through
255282 * creating cell objects or a generator or coroutine.
@@ -411,6 +438,7 @@ _PyFrame_PushTrampolineUnchecked(PyThreadState *tstate, PyCodeObject *code, int
411438 frame -> owner = FRAME_OWNED_BY_THREAD ;
412439 frame -> visited = 0 ;
413440#ifdef Py_DEBUG
441+ frame -> stackpointer_valid = 1 ;
414442 frame -> lltrace = 0 ;
415443#endif
416444 frame -> return_offset = 0 ;
0 commit comments