static PyObject * weakref_getweakrefs(PyObject *self, PyObject *object) { PyObject *result = NULL; if (PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) { PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); Py_ssize_t count = _PyWeakref_GetWeakrefCount(*list); result = PyList_New(count); if (result != NULL) { PyWeakReference *current = *list; Py_ssize_t i; for (i = 0; i < count; ++i) { PyList_SET_ITEM(result, i, (PyObject *) current); Py_INCREF(current); current = current->wr_next; } } } else { result = PyList_New(0); } return result; }
/* This function is called by the tp_dealloc handler to clear weak references. * * This iterates through the weak references for 'object' and calls callbacks * for those references which have one. It returns when all callbacks have * been attempted. */ void PyObject_ClearWeakRefs(PyObject *object) { PyWeakReference **list; if (object == NULL || !PyType_SUPPORTS_WEAKREFS(object->ob_type) || object->ob_refcnt != 0) { PyErr_BadInternalCall(); return; } list = GET_WEAKREFS_LISTPTR(object); /* Remove the callback-less basic and proxy references */ if (*list != NULL && (*list)->wr_callback == NULL) { clear_weakref(*list); if (*list != NULL && (*list)->wr_callback == NULL) clear_weakref(*list); } if (*list != NULL) { PyWeakReference *current = *list; int count = _PyWeakref_GetWeakrefCount(current); int restore_error = PyErr_Occurred() ? 1 : 0; PyObject *err_type, *err_value, *err_tb; if (restore_error) PyErr_Fetch(&err_type, &err_value, &err_tb); if (count == 1) { PyObject *callback = current->wr_callback; current->wr_callback = NULL; clear_weakref(current); handle_callback(current, callback); Py_DECREF(callback); } else { PyObject *tuple = PyTuple_New(count * 2); int i = 0; for (i = 0; i < count; ++i) { PyWeakReference *next = current->wr_next; Py_INCREF(current); PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); current->wr_callback = NULL; clear_weakref(current); current = next; } for (i = 0; i < count; ++i) { PyObject *current = PyTuple_GET_ITEM(tuple, i * 2); PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1); handle_callback((PyWeakReference *)current, callback); } Py_DECREF(tuple); } if (restore_error) PyErr_Restore(err_type, err_value, err_tb); } }
static Py_ssize_t _weakref_getweakrefcount_impl(PyObject *module, PyObject *object) /*[clinic end generated code: output=301806d59558ff3e input=cedb69711b6a2507]*/ { PyWeakReference **list; if (!PyType_SUPPORTS_WEAKREFS(Py_TYPE(object))) return 0; list = GET_WEAKREFS_LISTPTR(object); return _PyWeakref_GetWeakrefCount(*list); }
static PyObject * weakref_getweakrefcount(PyObject *self, PyObject *object) { PyObject *result = NULL; if (PyType_SUPPORTS_WEAKREFS(object->ob_type)) { PyWeakReference **list = GET_WEAKREFS_LISTPTR(object); result = PyInt_FromSsize_t(_PyWeakref_GetWeakrefCount(*list)); } else result = PyInt_FromLong(0); return result; }
/* This function is called by the tp_dealloc handler to clear weak references. * * This iterates through the weak references for 'object' and calls callbacks * for those references which have one. It returns when all callbacks have * been attempted. */ void PyObject_ClearWeakRefs(PyObject *object) { PyWeakReference **list; if (object == NULL || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)) //|| object->ob_refcnt != 0 ) { PyErr_BadInternalCall(); return; } list = GET_WEAKREFS_LISTPTR(object); /* Remove the callback-less basic and proxy references */ if (*list != NULL && (*list)->wr_callback == NULL) { clear_weakref(*list); if (*list != NULL && (*list)->wr_callback == NULL) clear_weakref(*list); } if (*list != NULL) { PyWeakReference *current = *list; Py_ssize_t count = _PyWeakref_GetWeakrefCount(current); int restore_error = PyErr_Occurred() ? 1 : 0; PyObject *err_type, *err_value, *err_tb; if (restore_error) PyErr_Fetch(&err_type, &err_value, &err_tb); if (count == 1) { PyObject *callback = current->wr_callback; current->wr_callback = NULL; clear_weakref(current); if (callback != NULL) { // Pyston change: // current is a stack reference to a GC allocated object. If it wasn't null when we fetched it from *list, it won't // be collected, and we can trust that it's still valid here. if (true /*current->ob_refcnt > 0*/) handle_callback(current, callback); Py_DECREF(callback); } } else { PyObject *tuple; Py_ssize_t i = 0; tuple = PyTuple_New(count * 2); if (tuple == NULL) { if (restore_error) PyErr_Fetch(&err_type, &err_value, &err_tb); return; } for (i = 0; i < count; ++i) { PyWeakReference *next = current->wr_next; // Pyston change: // current is a stack reference to a GC allocated object. If it wasn't null when we fetched it from *list, it won't // be collected, and we can trust that it's still valid here. if (true /*current->ob_refcnt > 0*/) { Py_INCREF(current); PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); } else { Py_DECREF(current->wr_callback); } current->wr_callback = NULL; clear_weakref(current); current = next; } for (i = 0; i < count; ++i) { PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1); /* The tuple may have slots left to NULL */ if (callback != NULL) { PyObject *item = PyTuple_GET_ITEM(tuple, i * 2); handle_callback((PyWeakReference *)item, callback); } } Py_DECREF(tuple); } if (restore_error) PyErr_Restore(err_type, err_value, err_tb); } }
/* This function is called by the tp_dealloc handler to clear weak references. * * This iterates through the weak references for 'object' and calls callbacks * for those references which have one. It returns when all callbacks have * been attempted. */ void PyObject_ClearWeakRefs(PyObject *object) { PyWeakReference **list; if (object == NULL || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)) || object->ob_refcnt != 0) { PyErr_BadInternalCall(); return; } list = GET_WEAKREFS_LISTPTR(object); /* Remove the callback-less basic and proxy references */ if (*list != NULL && (*list)->wr_callback == NULL) { clear_weakref(*list); if (*list != NULL && (*list)->wr_callback == NULL) clear_weakref(*list); } if (*list != NULL) { PyWeakReference *current = *list; Py_ssize_t count = _PyWeakref_GetWeakrefCount(current); PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); if (count == 1) { PyObject *callback = current->wr_callback; current->wr_callback = NULL; clear_weakref(current); if (callback != NULL) { if (current->ob_refcnt > 0) handle_callback(current, callback); Py_DECREF(callback); } } else { PyObject *tuple; Py_ssize_t i = 0; tuple = PyTuple_New(count * 2); if (tuple == NULL) { _PyErr_ReplaceException(err_type, err_value, err_tb); return; } for (i = 0; i < count; ++i) { PyWeakReference *next = current->wr_next; if (current->ob_refcnt > 0) { Py_INCREF(current); PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); } else { Py_DECREF(current->wr_callback); } current->wr_callback = NULL; clear_weakref(current); current = next; } for (i = 0; i < count; ++i) { PyObject *callback = PyTuple_GET_ITEM(tuple, i * 2 + 1); /* The tuple may have slots left to NULL */ if (callback != NULL) { PyObject *item = PyTuple_GET_ITEM(tuple, i * 2); handle_callback((PyWeakReference *)item, callback); } } Py_DECREF(tuple); } assert(!PyErr_Occurred()); PyErr_Restore(err_type, err_value, err_tb); } }