[Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.49,2.50 frameobject.c,2.37,2.38 listobject.c,2.66,2.67 object.c,2.63,2.64 tupleobject.c,2.29,2.30

Guido van Rossum guido@cnri.reston.va.us
Mon, 13 Mar 2000 11:01:33 -0500 (EST)


Update of /projects/cvsroot/python/dist/src/Objects
In directory eric:/home/guido/hp/mal/py-patched/Objects

Modified Files:
	dictobject.c frameobject.c listobject.c object.c tupleobject.c 
Log Message:
Christian Tismer's "trashcan" patch:

Added wrapping macros to dictobject.c, listobject.c, tupleobject.c,
frameobject.c, traceback.c that safely prevends core dumps 
on stack overflow. Macros and functions in object.c, object.h.
The method is an "elevator destructor" that turns cascading
deletes into tail recursive behavior when some limit is hit.


Index: dictobject.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/dictobject.c,v
retrieving revision 2.49
retrieving revision 2.50
diff -C2 -r2.49 -r2.50
*** dictobject.c	2000/02/23 15:47:16	2.49
--- dictobject.c	2000/03/13 16:01:29	2.50
***************
*** 480,483 ****
--- 480,484 ----
  	register int i;
  	register dictentry *ep;
+ 	Py_TRASHCAN_SAFE_BEGIN(mp)
  	for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) {
  		if (ep->me_key != NULL) {
***************
*** 490,493 ****
--- 491,495 ----
  	PyMem_XDEL(mp->ma_table);
  	PyMem_DEL(mp);
+ 	Py_TRASHCAN_SAFE_END(mp)
  }
  

Index: frameobject.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/frameobject.c,v
retrieving revision 2.37
retrieving revision 2.38
diff -C2 -r2.37 -r2.38
*** frameobject.c	2000/01/20 22:32:54	2.37
--- frameobject.c	2000/03/13 16:01:29	2.38
***************
*** 104,107 ****
--- 104,108 ----
  	PyObject **fastlocals;
  
+ 	Py_TRASHCAN_SAFE_BEGIN(f)
  	/* Kill all local variables */
  	fastlocals = f->f_localsplus;
***************
*** 121,124 ****
--- 122,126 ----
  	f->f_back = free_list;
  	free_list = f;
+ 	Py_TRASHCAN_SAFE_END(f)
  }
  

Index: listobject.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/listobject.c,v
retrieving revision 2.66
retrieving revision 2.67
diff -C2 -r2.66 -r2.67
*** listobject.c	2000/03/13 15:41:59	2.66
--- listobject.c	2000/03/13 16:01:29	2.67
***************
*** 216,219 ****
--- 216,220 ----
  {
  	int i;
+ 	Py_TRASHCAN_SAFE_BEGIN(op)
  	if (op->ob_item != NULL) {
  		/* Do it backwards, for Christian Tismer.
***************
*** 228,231 ****
--- 229,233 ----
  	}
  	free((ANY *)op);
+ 	Py_TRASHCAN_SAFE_END(op)
  }
  

Index: object.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/object.c,v
retrieving revision 2.63
retrieving revision 2.64
diff -C2 -r2.63 -r2.64
*** object.c	2000/03/10 22:55:18	2.63
--- object.c	2000/03/13 16:01:29	2.64
***************
*** 907,908 ****
--- 907,953 ----
  	}
  }
+ 
+ /*
+   trashcan
+   CT 2k0130
+   non-recursively destroy nested objects
+ 
+   CT 2k0223
+   everything is now done in a macro.
+ 
+   CT 2k0305
+   modified to use functions, after Tim Peter's suggestion.
+ 
+   CT 2k0309
+   modified to restore a possible error.
+ */
+ 
+ int _PyTrash_delete_nesting = 0;
+ PyObject * _PyTrash_delete_later = NULL;
+ 
+ void
+ _PyTrash_deposit_object(op)
+ 	PyObject *op;
+ {
+ 	PyObject *error_type, *error_value, *error_traceback;
+ 	PyErr_Fetch(&error_type, &error_value, &error_traceback);
+ 
+ 	if (!_PyTrash_delete_later)
+ 		_PyTrash_delete_later = PyList_New(0);
+ 	if (_PyTrash_delete_later)
+ 		PyList_Append(_PyTrash_delete_later, (PyObject *)op);
+ 
+ 	PyErr_Restore(error_type, error_value, error_traceback);
+ }
+ 
+ void
+ _PyTrash_destroy_list()
+ {
+ 	while (_PyTrash_delete_later) {
+ 		PyObject *shredder = _PyTrash_delete_later;
+ 		_PyTrash_delete_later = NULL;
+ 		++_PyTrash_delete_nesting;
+ 		Py_DECREF(shredder);
+ 		--_PyTrash_delete_nesting;
+ 	}
+ }

Index: tupleobject.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Objects/tupleobject.c,v
retrieving revision 2.29
retrieving revision 2.30
diff -C2 -r2.29 -r2.30
*** tupleobject.c	2000/01/20 22:32:54	2.29
--- tupleobject.c	2000/03/13 16:01:29	2.30
***************
*** 173,176 ****
--- 173,177 ----
  	register int i;
  
+ 	Py_TRASHCAN_SAFE_BEGIN(op)
  	if (op->ob_size > 0) {
  		i = op->ob_size;
***************
*** 181,189 ****
  			op->ob_item[0] = (PyObject *) free_tuples[op->ob_size];
  			free_tuples[op->ob_size] = op;
! 			return;
  		}
  #endif
  	}
  	free((ANY *)op);
  }
  
--- 182,192 ----
  			op->ob_item[0] = (PyObject *) free_tuples[op->ob_size];
  			free_tuples[op->ob_size] = op;
! 			goto done; /* return */
  		}
  #endif
  	}
  	free((ANY *)op);
+ done:
+ 	Py_TRASHCAN_SAFE_END(op)
  }