diff options
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/weakrefobject.c | 119 |
1 files changed, 88 insertions, 31 deletions
diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index daee476..bf79e0c 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -145,11 +145,14 @@ weakref_hash(PyWeakReference *self) { if (self->hash != -1) return self->hash; - if (PyWeakref_GET_OBJECT(self) == Py_None) { + PyObject* obj = PyWeakref_GET_OBJECT(self); + if (obj == Py_None) { PyErr_SetString(PyExc_TypeError, "weak object has gone away"); return -1; } - self->hash = PyObject_Hash(PyWeakref_GET_OBJECT(self)); + Py_INCREF(obj); + self->hash = PyObject_Hash(obj); + Py_DECREF(obj); return self->hash; } @@ -159,11 +162,15 @@ weakref_repr(PyWeakReference *self) { PyObject *name, *repr; _Py_IDENTIFIER(__name__); + PyObject* obj = PyWeakref_GET_OBJECT(self); - if (PyWeakref_GET_OBJECT(self) == Py_None) + if (obj == Py_None) { return PyUnicode_FromFormat("<weakref at %p; dead>", self); + } - if (_PyObject_LookupAttrId(PyWeakref_GET_OBJECT(self), &PyId___name__, &name) < 0) { + Py_INCREF(obj); + if (_PyObject_LookupAttrId(obj, &PyId___name__, &name) < 0) { + Py_DECREF(obj); return NULL; } if (name == NULL || !PyUnicode_Check(name)) { @@ -171,16 +178,17 @@ weakref_repr(PyWeakReference *self) "<weakref at %p; to '%s' at %p>", self, Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, - PyWeakref_GET_OBJECT(self)); + obj); } else { repr = PyUnicode_FromFormat( "<weakref at %p; to '%s' at %p (%U)>", self, Py_TYPE(PyWeakref_GET_OBJECT(self))->tp_name, - PyWeakref_GET_OBJECT(self), + obj, name); } + Py_DECREF(obj); Py_XDECREF(name); return repr; } @@ -207,8 +215,14 @@ weakref_richcompare(PyWeakReference* self, PyWeakReference* other, int op) else Py_RETURN_FALSE; } - return PyObject_RichCompare(PyWeakref_GET_OBJECT(self), - PyWeakref_GET_OBJECT(other), op); + PyObject* obj = PyWeakref_GET_OBJECT(self); + PyObject* other_obj = PyWeakref_GET_OBJECT(other); + Py_INCREF(obj); + Py_INCREF(other_obj); + PyObject* res = PyObject_RichCompare(obj, other_obj, op); + Py_DECREF(obj); + Py_DECREF(other_obj); + return res; } /* Given the head of an object's list of weak references, extract the @@ -415,18 +429,14 @@ proxy_checkref(PyWeakReference *proxy) o = PyWeakref_GET_OBJECT(o); \ } -#define UNWRAP_I(o) \ - if (PyWeakref_CheckProxy(o)) { \ - if (!proxy_checkref((PyWeakReference *)o)) \ - return -1; \ - o = PyWeakref_GET_OBJECT(o); \ - } - #define WRAP_UNARY(method, generic) \ static PyObject * \ method(PyObject *proxy) { \ UNWRAP(proxy); \ - return generic(proxy); \ + Py_INCREF(proxy); \ + PyObject* res = generic(proxy); \ + Py_DECREF(proxy); \ + return res; \ } #define WRAP_BINARY(method, generic) \ @@ -434,7 +444,12 @@ proxy_checkref(PyWeakReference *proxy) method(PyObject *x, PyObject *y) { \ UNWRAP(x); \ UNWRAP(y); \ - return generic(x, y); \ + Py_INCREF(x); \ + Py_INCREF(y); \ + PyObject* res = generic(x, y); \ + Py_DECREF(x); \ + Py_DECREF(y); \ + return res; \ } /* Note that the third arg needs to be checked for NULL since the tp_call @@ -447,7 +462,14 @@ proxy_checkref(PyWeakReference *proxy) UNWRAP(v); \ if (w != NULL) \ UNWRAP(w); \ - return generic(proxy, v, w); \ + Py_INCREF(proxy); \ + Py_INCREF(v); \ + Py_XINCREF(w); \ + PyObject* res = generic(proxy, v, w); \ + Py_DECREF(proxy); \ + Py_DECREF(v); \ + Py_XDECREF(w); \ + return res; \ } #define WRAP_METHOD(method, special) \ @@ -455,7 +477,10 @@ proxy_checkref(PyWeakReference *proxy) method(PyObject *proxy, PyObject *Py_UNUSED(ignored)) { \ _Py_IDENTIFIER(special); \ UNWRAP(proxy); \ - return _PyObject_CallMethodIdNoArgs(proxy, &PyId_##special); \ + Py_INCREF(proxy); \ + PyObject* res = _PyObject_CallMethodIdNoArgs(proxy, &PyId_##special); \ + Py_DECREF(proxy); \ + return res; \ } @@ -481,7 +506,11 @@ proxy_setattr(PyWeakReference *proxy, PyObject *name, PyObject *value) { if (!proxy_checkref(proxy)) return -1; - return PyObject_SetAttr(PyWeakref_GET_OBJECT(proxy), name, value); + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res = PyObject_SetAttr(obj, name, value); + Py_DECREF(obj); + return res; } static PyObject * @@ -532,9 +561,13 @@ static int proxy_bool(PyWeakReference *proxy) { PyObject *o = PyWeakref_GET_OBJECT(proxy); - if (!proxy_checkref(proxy)) + if (!proxy_checkref(proxy)) { return -1; - return PyObject_IsTrue(o); + } + Py_INCREF(o); + int res = PyObject_IsTrue(o); + Py_DECREF(o); + return res; } static void @@ -553,9 +586,13 @@ proxy_contains(PyWeakReference *proxy, PyObject *value) { if (!proxy_checkref(proxy)) return -1; - return PySequence_Contains(PyWeakref_GET_OBJECT(proxy), value); -} + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res = PySequence_Contains(obj, value); + Py_DECREF(obj); + return res; +} /* mapping slots */ @@ -564,7 +601,12 @@ proxy_length(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return -1; - return PyObject_Length(PyWeakref_GET_OBJECT(proxy)); + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + Py_ssize_t res = PyObject_Length(obj); + Py_DECREF(obj); + return res; } WRAP_BINARY(proxy_getitem, PyObject_GetItem) @@ -575,10 +617,16 @@ proxy_setitem(PyWeakReference *proxy, PyObject *key, PyObject *value) if (!proxy_checkref(proxy)) return -1; - if (value == NULL) - return PyObject_DelItem(PyWeakref_GET_OBJECT(proxy), key); - else - return PyObject_SetItem(PyWeakref_GET_OBJECT(proxy), key, value); + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + int res; + if (value == NULL) { + res = PyObject_DelItem(obj, key); + } else { + res = PyObject_SetItem(obj, key, value); + } + Py_DECREF(obj); + return res; } /* iterator slots */ @@ -588,7 +636,11 @@ proxy_iter(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return NULL; - return PyObject_GetIter(PyWeakref_GET_OBJECT(proxy)); + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + PyObject* res = PyObject_GetIter(obj); + Py_DECREF(obj); + return res; } static PyObject * @@ -596,7 +648,12 @@ proxy_iternext(PyWeakReference *proxy) { if (!proxy_checkref(proxy)) return NULL; - return PyIter_Next(PyWeakref_GET_OBJECT(proxy)); + + PyObject *obj = PyWeakref_GET_OBJECT(proxy); + Py_INCREF(obj); + PyObject* res = PyIter_Next(obj); + Py_DECREF(obj); + return res; } |