From 8c96369513ded66146f9cf19678029615e29bcb7 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Sat, 23 Jun 2001 05:26:56 +0000 Subject: [PATCH] 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 ). 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. --- Include/frameobject.h | 6 ++++-- Objects/frameobject.c | 8 +++++--- Python/ceval.c | 10 +++++----- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Include/frameobject.h b/Include/frameobject.h index b620f7652fa..e2bf7a1ef60 100644 --- a/Include/frameobject.h +++ b/Include/frameobject.h @@ -21,8 +21,10 @@ typedef struct _frame { PyObject *f_globals; /* global symbol table (PyDictObject) */ PyObject *f_locals; /* local symbol table (PyDictObject) */ PyObject **f_valuestack; /* points after the last local */ - PyObject **f_stackbottom; /* points to the last item on the stack if - frame has yielded. */ + /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. + Frame evaluation usually NULLs it, but a frame that yields sets it + to the current stack top. */ + PyObject **f_stacktop; PyObject *f_trace; /* Trace function */ PyObject *f_exc_type, *f_exc_value, *f_exc_traceback; PyThreadState *f_tstate; diff --git a/Objects/frameobject.c b/Objects/frameobject.c index c38c5fbc250..6af4e6e88ad 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -78,9 +78,11 @@ frame_dealloc(PyFrameObject *f) } /* Free stack */ - for (p = f->f_valuestack; p < f->f_stackbottom; p++) { - Py_XDECREF(*p); + if (f->f_stacktop != NULL) { + for (p = f->f_valuestack; p < f->f_stacktop; p++) + Py_XDECREF(*p); } + Py_XDECREF(f->f_back); Py_XDECREF(f->f_code); Py_XDECREF(f->f_builtins); @@ -226,7 +228,7 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, f->f_localsplus[extras] = NULL; f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees); - f->f_stackbottom = f->f_valuestack; + f->f_stacktop = f->f_valuestack; return f; } diff --git a/Python/ceval.c b/Python/ceval.c index fcb8fc3e058..d6b61d5b42f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -147,9 +147,8 @@ gen_iternext(genobject *gen) "generator already executing"); return NULL; } - if (f->f_stackbottom == NULL) { + if (f->f_stacktop == NULL) return NULL; - } /* Generators always return to their most recent caller, not * necessarily their creator. */ @@ -584,8 +583,9 @@ eval_frame(PyFrameObject *f) freevars = f->f_localsplus + f->f_nlocals; _PyCode_GETCODEPTR(co, &first_instr); next_instr = first_instr + f->f_lasti; - stack_pointer = f->f_stackbottom; - f->f_stackbottom = NULL; + stack_pointer = f->f_stacktop; + assert(stack_pointer != NULL); + f->f_stacktop = NULL; #ifdef LLTRACE lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL; @@ -1371,7 +1371,7 @@ eval_frame(PyFrameObject *f) case YIELD_VALUE: retval = POP(); - f->f_stackbottom = stack_pointer; + f->f_stacktop = stack_pointer; f->f_lasti = INSTR_OFFSET(); why = WHY_YIELD; break;