[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);
  	}