Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8c96369

Browse files
committed
PyFrameObject: rename f_stackbottom to f_stacktop, since it points to
the next free valuestack slot, not to the base (in America, stacks push and pop at the top -- they mutate at the bottom in Australia <winK>). eval_frame(): assert that f_stacktop isn't NULL upon entry. frame_delloc(): avoid ordered pointer comparisons involving f_stacktop when f_stacktop is NULL.
1 parent f5eae66 commit 8c96369

3 files changed

Lines changed: 14 additions & 10 deletions

File tree

Include/frameobject.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ typedef struct _frame {
2121
PyObject *f_globals; /* global symbol table (PyDictObject) */
2222
PyObject *f_locals; /* local symbol table (PyDictObject) */
2323
PyObject **f_valuestack; /* points after the last local */
24-
PyObject **f_stackbottom; /* points to the last item on the stack if
25-
frame has yielded. */
24+
/* Next free slot in f_valuestack. Frame creation sets to f_valuestack.
25+
Frame evaluation usually NULLs it, but a frame that yields sets it
26+
to the current stack top. */
27+
PyObject **f_stacktop;
2628
PyObject *f_trace; /* Trace function */
2729
PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
2830
PyThreadState *f_tstate;

Objects/frameobject.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,11 @@ frame_dealloc(PyFrameObject *f)
7878
}
7979

8080
/* Free stack */
81-
for (p = f->f_valuestack; p < f->f_stackbottom; p++) {
82-
Py_XDECREF(*p);
81+
if (f->f_stacktop != NULL) {
82+
for (p = f->f_valuestack; p < f->f_stacktop; p++)
83+
Py_XDECREF(*p);
8384
}
85+
8486
Py_XDECREF(f->f_back);
8587
Py_XDECREF(f->f_code);
8688
Py_XDECREF(f->f_builtins);
@@ -226,7 +228,7 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
226228
f->f_localsplus[extras] = NULL;
227229

228230
f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees);
229-
f->f_stackbottom = f->f_valuestack;
231+
f->f_stacktop = f->f_valuestack;
230232

231233
return f;
232234
}

Python/ceval.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,8 @@ gen_iternext(genobject *gen)
147147
"generator already executing");
148148
return NULL;
149149
}
150-
if (f->f_stackbottom == NULL) {
150+
if (f->f_stacktop == NULL)
151151
return NULL;
152-
}
153152

154153
/* Generators always return to their most recent caller, not
155154
* necessarily their creator. */
@@ -584,8 +583,9 @@ eval_frame(PyFrameObject *f)
584583
freevars = f->f_localsplus + f->f_nlocals;
585584
_PyCode_GETCODEPTR(co, &first_instr);
586585
next_instr = first_instr + f->f_lasti;
587-
stack_pointer = f->f_stackbottom;
588-
f->f_stackbottom = NULL;
586+
stack_pointer = f->f_stacktop;
587+
assert(stack_pointer != NULL);
588+
f->f_stacktop = NULL;
589589

590590
#ifdef LLTRACE
591591
lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL;
@@ -1371,7 +1371,7 @@ eval_frame(PyFrameObject *f)
13711371

13721372
case YIELD_VALUE:
13731373
retval = POP();
1374-
f->f_stackbottom = stack_pointer;
1374+
f->f_stacktop = stack_pointer;
13751375
f->f_lasti = INSTR_OFFSET();
13761376
why = WHY_YIELD;
13771377
break;

0 commit comments

Comments
 (0)