cinap_lenrekadd hg and python4bb9e2215 years agoHistory
2139 lines · 49.8 KB · C
RawDownload
 void *PyMem_Malloc(size_t nbytes){	return PyMem_MALLOC(nbytes);} void *PyMem_Realloc(void *p, size_t nbytes){	return PyMem_REALLOC(p, nbytes);} voidPyMem_Free(void *p){	PyMem_FREE(p);}  /* These methods are used to control infinite recursion in repr, str, print,   etc.  Container objects that may recursively contain themselves,   e.g. builtin dictionaries and lists, should used Py_ReprEnter() and   Py_ReprLeave() to avoid infinite recursion.    Py_ReprEnter() returns 0 the first time it is called for a particular   object and 1 every time thereafter.  It returns -1 if an exception   occurred.  Py_ReprLeave() has no return value.    See dictobject.c and listobject.c for examples of use.*/ #define KEY "Py_Repr" intPy_ReprEnter(PyObject *obj){	PyObject *dict;	PyObject *list;	Py_ssize_t i; 	dict = PyThreadState_GetDict();	if (dict == NULL)		return 0;	list = PyDict_GetItemString(dict, KEY);	if (list == NULL) {		list = PyList_New(0);		if (list == NULL)			return -1;		if (PyDict_SetItemString(dict, KEY, list) < 0)			return -1;		Py_DECREF(list);	}	i = PyList_GET_SIZE(list);	while (--i >= 0) {		if (PyList_GET_ITEM(list, i) == obj)			return 1;	}	PyList_Append(list, obj);	return 0;} voidPy_ReprLeave(PyObject *obj){	PyObject *dict;	PyObject *list;	Py_ssize_t i; 	dict = PyThreadState_GetDict();	if (dict == NULL)		return;	list = PyDict_GetItemString(dict, KEY);	if (list == NULL || !PyList_Check(list))		return;	i = PyList_GET_SIZE(list);	/* Count backwards because we always expect obj to be list[-1] */	while (--i >= 0) {		if (PyList_GET_ITEM(list, i) == obj) {			PyList_SetSlice(list, i, i + 1, NULL);			break;		}	}} /* Trashcan support. */ /* Current call-stack depth of tp_dealloc calls. */int _PyTrash_delete_nesting = 0; /* List of objects that still need to be cleaned up, singly linked via their * gc headers' gc_prev pointers. */PyObject *_PyTrash_delete_later = NULL; /* Add op to the _PyTrash_delete_later list.  Called when the current * call-stack depth gets large.  op must be a currently untracked gc'ed * object, with refcount 0.  Py_DECREF must already have been called on it. */void_PyTrash_deposit_object(PyObject *op){	assert(PyObject_IS_GC(op));	assert(_Py_AS_GC(op)->gc.gc_refs == _PyGC_REFS_UNTRACKED);	assert(op->ob_refcnt == 0);	_Py_AS_GC(op)->gc.gc_prev = (PyGC_Head *)_PyTrash_delete_later;	_PyTrash_delete_later = op;} /* Dealloccate all the objects in the _PyTrash_delete_later list.  Called when * the call-stack unwinds again. */void_PyTrash_destroy_chain(void){	while (_PyTrash_delete_later) {		PyObject *op = _PyTrash_delete_later;		destructor dealloc = op->ob_type->tp_dealloc; 		_PyTrash_delete_later =			(PyObject*) _Py_AS_GC(op)->gc.gc_prev; 		/* Call the deallocator directly.  This used to try to		 * fool Py_DECREF into calling it indirectly, but		 * Py_DECREF was already called on this object, and in		 * assorted non-release builds calling Py_DECREF again ends		 * up distorting allocation statistics.		 */		assert(op->ob_refcnt == 0);		++_PyTrash_delete_nesting;		(*dealloc)(op);		--_PyTrash_delete_nesting;	}} #ifdef __cplusplus}#endif 

Lines 2001–2139 of 2139. Previous lines