summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/frameobject.h6
-rw-r--r--Objects/frameobject.c8
-rw-r--r--Python/ceval.c10
3 files changed, 14 insertions, 10 deletions
diff --git a/Include/frameobject.h b/Include/frameobject.h
index b620f76..e2bf7a1 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 c38c5fb..6af4e6e 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 fcb8fc3..d6b61d5 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;