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.
This commit is contained in:
Tim Peters 2001-06-23 05:26:56 +00:00
parent f5eae668a8
commit 8c96369513
3 changed files with 14 additions and 10 deletions

View File

@ -21,8 +21,10 @@ typedef struct _frame {
PyObject *f_globals; /* global symbol table (PyDictObject) */ PyObject *f_globals; /* global symbol table (PyDictObject) */
PyObject *f_locals; /* local symbol table (PyDictObject) */ PyObject *f_locals; /* local symbol table (PyDictObject) */
PyObject **f_valuestack; /* points after the last local */ PyObject **f_valuestack; /* points after the last local */
PyObject **f_stackbottom; /* points to the last item on the stack if /* Next free slot in f_valuestack. Frame creation sets to f_valuestack.
frame has yielded. */ 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_trace; /* Trace function */
PyObject *f_exc_type, *f_exc_value, *f_exc_traceback; PyObject *f_exc_type, *f_exc_value, *f_exc_traceback;
PyThreadState *f_tstate; PyThreadState *f_tstate;

View File

@ -78,9 +78,11 @@ frame_dealloc(PyFrameObject *f)
} }
/* Free stack */ /* Free stack */
for (p = f->f_valuestack; p < f->f_stackbottom; p++) { if (f->f_stacktop != NULL) {
Py_XDECREF(*p); for (p = f->f_valuestack; p < f->f_stacktop; p++)
Py_XDECREF(*p);
} }
Py_XDECREF(f->f_back); Py_XDECREF(f->f_back);
Py_XDECREF(f->f_code); Py_XDECREF(f->f_code);
Py_XDECREF(f->f_builtins); Py_XDECREF(f->f_builtins);
@ -226,7 +228,7 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
f->f_localsplus[extras] = NULL; f->f_localsplus[extras] = NULL;
f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees); 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; return f;
} }

View File

@ -147,9 +147,8 @@ gen_iternext(genobject *gen)
"generator already executing"); "generator already executing");
return NULL; return NULL;
} }
if (f->f_stackbottom == NULL) { if (f->f_stacktop == NULL)
return NULL; return NULL;
}
/* Generators always return to their most recent caller, not /* Generators always return to their most recent caller, not
* necessarily their creator. */ * necessarily their creator. */
@ -584,8 +583,9 @@ eval_frame(PyFrameObject *f)
freevars = f->f_localsplus + f->f_nlocals; freevars = f->f_localsplus + f->f_nlocals;
_PyCode_GETCODEPTR(co, &first_instr); _PyCode_GETCODEPTR(co, &first_instr);
next_instr = first_instr + f->f_lasti; next_instr = first_instr + f->f_lasti;
stack_pointer = f->f_stackbottom; stack_pointer = f->f_stacktop;
f->f_stackbottom = NULL; assert(stack_pointer != NULL);
f->f_stacktop = NULL;
#ifdef LLTRACE #ifdef LLTRACE
lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL; lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL;
@ -1371,7 +1371,7 @@ eval_frame(PyFrameObject *f)
case YIELD_VALUE: case YIELD_VALUE:
retval = POP(); retval = POP();
f->f_stackbottom = stack_pointer; f->f_stacktop = stack_pointer;
f->f_lasti = INSTR_OFFSET(); f->f_lasti = INSTR_OFFSET();
why = WHY_YIELD; why = WHY_YIELD;
break; break;