[Python-checkins] CVS: python/dist/src/Objects frameobject.c,2.46,2.47

Jeremy Hylton jhylton@users.sourceforge.net
Wed, 21 Mar 2001 08:43:49 -0800


Update of /cvsroot/python/python/dist/src/Objects
In directory usw-pr-cvs1:/tmp/cvs-serv32376/Objects

Modified Files:
	frameobject.c 
Log Message:
Fix PyFrame_FastToLocals() and counterpart to deal with cells and
frees.  Note there doesn't seem to be any way to test LocalsToFast(),
because the instructions that trigger it are illegal in nested scopes
with free variables.

Fix allocation strategy for cells that are also formal parameters.
Instead of emitting LOAD_FAST / STORE_DEREF pairs for each parameter,
have the argument handling code in eval_code2() do the right thing.

A side-effect of this change is that cell variables that are also
arguments are listed at the front of co_cellvars in the order they
appear in the argument list.



Index: frameobject.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v
retrieving revision 2.46
retrieving revision 2.47
diff -C2 -r2.46 -r2.47
*** frameobject.c	2001/03/13 01:58:21	2.46
--- frameobject.c	2001/03/21 16:43:45	2.47
***************
*** 252,256 ****
  /* Convert between "fast" version of locals and dictionary version */
  
! /* XXX should also copy free variables and cell variables */
  
  void
--- 252,300 ----
  /* Convert between "fast" version of locals and dictionary version */
  
! void
! map_to_dict(PyObject *map, int nmap, PyObject *dict, PyObject **values,
! 	    int deref)
! {
! 	int j;
! 	for (j = nmap; --j >= 0; ) {
! 		PyObject *key = PyTuple_GetItem(map, j);
! 		PyObject *value = values[j];
! 		if (deref)
! 			value = PyCell_GET(value);
! 		if (value == NULL) {
! 			PyErr_Clear();
! 			if (PyDict_DelItem(dict, key) != 0)
! 				PyErr_Clear();
! 		}
! 		else {
! 			if (PyDict_SetItem(dict, key, value) != 0)
! 				PyErr_Clear();
! 		}
! 	}
! }
! 
! void
! dict_to_map(PyObject *map, int nmap, PyObject *dict, PyObject **values,
! 	    int deref, int clear)
! {
! 	int j;
! 	for (j = nmap; --j >= 0; ) {
! 		PyObject *key = PyTuple_GetItem(map, j);
! 		PyObject *value = PyDict_GetItem(dict, key);
! 		Py_XINCREF(value);
! 		if (deref) {
! 			if (value) {
! 				if (PyCell_Set(values[j], value) < 0)
! 					PyErr_Clear();
! 			} else if (clear) {
! 				Py_XDECREF(values[j]);
! 				values[j] = value;
! 			}
! 		} else if (value != NULL || clear) {
! 			Py_XDECREF(values[j]);
! 			values[j] = value;
! 		}
! 	}
! }
  
  void
***************
*** 282,297 ****
  	if (j > f->f_nlocals)
  		j = f->f_nlocals;
! 	for (; --j >= 0; ) {
! 		PyObject *key = PyTuple_GetItem(map, j);
! 		PyObject *value = fast[j];
! 		if (value == NULL) {
! 			PyErr_Clear();
! 			if (PyDict_DelItem(locals, key) != 0)
! 				PyErr_Clear();
! 		}
! 		else {
! 			if (PyDict_SetItem(locals, key, value) != 0)
! 				PyErr_Clear();
  		}
  	}
  	PyErr_Restore(error_type, error_value, error_traceback);
--- 326,342 ----
  	if (j > f->f_nlocals)
  		j = f->f_nlocals;
! 	map_to_dict(map, j, locals, fast, 0);
! 	if (f->f_ncells || f->f_nfreevars) {
! 		if (!(PyTuple_Check(f->f_code->co_cellvars)
! 		      && PyTuple_Check(f->f_code->co_freevars))) {
! 			Py_DECREF(locals);
! 			return;
  		}
+ 		map_to_dict(f->f_code->co_cellvars, 
+ 			    PyTuple_GET_SIZE(f->f_code->co_cellvars),
+ 			    locals, fast + f->f_nlocals, 1);
+ 		map_to_dict(f->f_code->co_freevars, 
+ 			    PyTuple_GET_SIZE(f->f_code->co_freevars),
+ 			    locals, fast + f->f_nlocals + f->f_ncells, 1);
  	}
  	PyErr_Restore(error_type, error_value, error_traceback);
***************
*** 319,330 ****
  	if (j > f->f_nlocals)
  		j = f->f_nlocals;
! 	for (; --j >= 0; ) {
! 		PyObject *key = PyTuple_GetItem(map, j);
! 		PyObject *value = PyDict_GetItem(locals, key);
! 		Py_XINCREF(value);
! 		if (value != NULL || clear) {
! 			Py_XDECREF(fast[j]);
! 			fast[j] = value;
! 		}
  	}
  	PyErr_Restore(error_type, error_value, error_traceback);
--- 364,378 ----
  	if (j > f->f_nlocals)
  		j = f->f_nlocals;
! 	dict_to_map(f->f_code->co_varnames, j, locals, fast, 0, clear);
! 	if (f->f_ncells || f->f_nfreevars) {
! 		if (!(PyTuple_Check(f->f_code->co_cellvars)
! 		      && PyTuple_Check(f->f_code->co_freevars)))
! 			return;
! 		dict_to_map(f->f_code->co_cellvars, 
! 			    PyTuple_GET_SIZE(f->f_code->co_cellvars),
! 			    locals, fast, 1, clear);
! 		dict_to_map(f->f_code->co_freevars, 
! 			    PyTuple_GET_SIZE(f->f_code->co_freevars),
! 			    locals, fast, 1, clear);
  	}
  	PyErr_Restore(error_type, error_value, error_traceback);