Skip to content

Commit fe00513

Browse files
committed
Tweak handling of f_stackdepth.
1 parent a7e7f75 commit fe00513

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

Objects/frameobject.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ first_line_not_before(int *lines, int len, int line)
300300
static void
301301
frame_stack_pop(PyFrameObject *f)
302302
{
303+
assert(f->f_stackdepth >= 0);
303304
f->f_stackdepth--;
304305
PyObject *v = f->f_valuestack[f->f_stackdepth];
305306
Py_DECREF(v);
@@ -308,6 +309,7 @@ frame_stack_pop(PyFrameObject *f)
308309
static void
309310
frame_block_unwind(PyFrameObject *f)
310311
{
312+
assert(f->f_stackdepth >= 0);
311313
assert(f->f_iblock > 0);
312314
f->f_iblock--;
313315
PyTryBlock *b = &f->f_blockstack[f->f_iblock];

Python/ceval.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,8 +1350,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
13501350
next_instr += f->f_lasti / sizeof(_Py_CODEUNIT) + 1;
13511351
}
13521352
stack_pointer = f->f_valuestack + f->f_stackdepth;
1353-
/* To help with debugging, set f->f_stackdepth to -1.
1354-
* Update when returning or calling trace function */
1353+
/* Set f->f_stackdepth to -1.
1354+
* Update when returning or calling trace function.
1355+
Having f_stackdepth <= 0 ensures that invalid
1356+
values are not visible to the cycle GC.
1357+
We choose -1 rather than 0 to assist debugging.
1358+
*/
13551359
f->f_stackdepth = -1;
13561360
f->f_state = FRAME_EXECUTING;
13571361

@@ -1450,6 +1454,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
14501454
/* Reload possibly changed frame fields */
14511455
JUMPTO(f->f_lasti);
14521456
stack_pointer = f->f_valuestack+f->f_stackdepth;
1457+
f->f_stackdepth = -1;
14531458
if (err)
14541459
/* trace function raised an exception */
14551460
goto error;
@@ -2075,6 +2080,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
20752080
assert(f->f_iblock == 0);
20762081
assert(EMPTY());
20772082
f->f_state = FRAME_RETURNED;
2083+
f->f_stackdepth = 0;
20782084
goto exiting;
20792085
}
20802086

@@ -2245,6 +2251,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
22452251
assert(f->f_lasti >= (int)sizeof(_Py_CODEUNIT));
22462252
f->f_lasti -= sizeof(_Py_CODEUNIT);
22472253
f->f_state = FRAME_SUSPENDED;
2254+
f->f_stackdepth = stack_pointer-f->f_valuestack;
22482255
goto exiting;
22492256
}
22502257

@@ -2261,6 +2268,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
22612268
retval = w;
22622269
}
22632270
f->f_state = FRAME_SUSPENDED;
2271+
f->f_stackdepth = stack_pointer-f->f_valuestack;
22642272
goto exiting;
22652273
}
22662274

@@ -3843,10 +3851,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
38433851
PyObject *o = POP();
38443852
Py_XDECREF(o);
38453853
}
3846-
3854+
f->f_stackdepth = 0;
38473855
f->f_state = FRAME_RAISED;
38483856
exiting:
3849-
f->f_stackdepth = stack_pointer-f->f_valuestack;
38503857
if (tstate->use_tracing) {
38513858
if (tstate->c_tracefunc) {
38523859
if (call_trace_protected(tstate->c_tracefunc, tstate->c_traceobj,

0 commit comments

Comments
 (0)