[Python-checkins] CVS: python/dist/src/Python ceval.c,2.251,2.252
Neil Schemenauer
nascheme@users.sourceforge.net
Wed, 20 Jun 2001 19:41:12 -0700
Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv2845/Python
Modified Files:
ceval.c
Log Message:
Try to avoid creating reference cycles involving generators. Only keep a
reference to f_back when its really needed. Do a little whitespace
normalization as well. This whole file is a big war between tabs and spaces
but now is probably not the time to reindent everything.
Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.251
retrieving revision 2.252
diff -C2 -r2.251 -r2.252
*** ceval.c 2001/06/20 06:57:32 2.251
--- ceval.c 2001/06/21 02:41:10 2.252
***************
*** 139,142 ****
--- 139,143 ----
gen_iternext(genobject *gen)
{
+ PyThreadState *tstate = PyThreadState_GET();
PyFrameObject *f = gen->frame;
PyObject *result;
***************
*** 150,162 ****
return NULL;
}
! gen->running = 1;
result = eval_frame(f);
! gen->running = 0;
! /* The connection between this frame and its parent is over now, so
! must NULL out f_back lest it get decref'ed when gen dies (note
! that eval_frame sets f->f_back without bumping its refcount: we
! never had a fully legit reference to it). */
f->f_back = NULL;
! return result;
}
--- 151,172 ----
return NULL;
}
!
! /* Generators always return to their most recent caller, not
! * necessarily their creator. */
! Py_INCREF(tstate->frame);
! assert(f->f_back == NULL);
! f->f_back = tstate->frame;
!
! gen->running = 1;
result = eval_frame(f);
! gen->running = 0;
!
! /* Don't keep the reference to f_back any longer than necessary. It
! * may keep a chain of frames alive or it could create a reference
! * cycle. */
! Py_DECREF(f->f_back);
f->f_back = NULL;
!
! return result;
}
***************
*** 169,178 ****
return NULL;
! result = gen_iternext(gen);
! if (result == NULL && !PyErr_Occurred()) {
PyErr_SetObject(PyExc_StopIteration, Py_None);
return NULL;
! }
return result;
--- 179,188 ----
return NULL;
! result = gen_iternext(gen);
! if (result == NULL && !PyErr_Occurred()) {
PyErr_SetObject(PyExc_StopIteration, Py_None);
return NULL;
! }
return result;
***************
*** 569,575 ****
}
- f->f_back = tstate->frame;
tstate->frame = f;
-
co = f->f_code;
fastlocals = f->f_localsplus;
--- 579,583 ----
***************
*** 2483,2488 ****
if (co->co_flags & CO_GENERATOR) {
! /* create a new generator that owns the ready to run frame
! * and return that as the value */
return gen_new(f);
}
--- 2491,2501 ----
if (co->co_flags & CO_GENERATOR) {
! /* Don't need to keep the reference to f_back, it will be set
! * when the generator is resumed. */
! Py_DECREF(f->f_back);
! f->f_back = NULL;
!
! /* Create a new generator that owns the ready to run frame
! * and return that as the value. */
return gen_new(f);
}