[pypy-commit] cffi default: Allow weakrefs to any cdata object, prompted by issue 12.

arigo noreply at buildbot.pypy.org
Wed Aug 8 17:28:36 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r791:98d3cd7588bf
Date: 2012-08-08 17:15 +0200
http://bitbucket.org/cffi/cffi/changeset/98d3cd7588bf/

Log:	Allow weakrefs to any cdata object, prompted by issue 12.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -77,6 +77,7 @@
     PyObject_HEAD
     CTypeDescrObject *c_type;
     char *c_data;
+    PyObject *c_weakreflist;
 } CDataObject;
 
 typedef struct cfieldobject_s {
@@ -118,22 +119,17 @@
 
 typedef struct {
     CDataObject head;
-    PyObject *weakreflist;
-} CDataObject_own_base;
-
-typedef struct {
-    CDataObject_own_base head;
     union_alignment alignment;
 } CDataObject_own_nolength;
 
 typedef struct {
-    CDataObject_own_base head;
+    CDataObject head;
     Py_ssize_t length;
     union_alignment alignment;
 } CDataObject_own_length;
 
 typedef struct {
-    CDataObject_own_base head;
+    CDataObject head;
     PyObject *structobj;
 } CDataObject_own_structptr;
 
@@ -542,6 +538,7 @@
     Py_INCREF(ct);
     cd->c_data = data;
     cd->c_type = ct;
+    cd->c_weakreflist = NULL;
     return (PyObject *)cd;
 }
 
@@ -1135,26 +1132,26 @@
 
 static void cdata_dealloc(CDataObject *cd)
 {
+    if (cd->c_weakreflist != NULL)
+        PyObject_ClearWeakRefs((PyObject *) cd);
+
     Py_DECREF(cd->c_type);
     PyObject_Del(cd);
 }
 
-static void cdataowning_dealloc(CDataObject_own_base *cdb)
+static void cdataowning_dealloc(CDataObject *cd)
 {
-    if (cdb->weakreflist != NULL)
-        PyObject_ClearWeakRefs((PyObject *) cdb);
-
-    if (cdb->head.c_type->ct_flags & CT_IS_PTR_TO_OWNED) {
-        Py_DECREF(((CDataObject_own_structptr *)cdb)->structobj);
+    if (cd->c_type->ct_flags & CT_IS_PTR_TO_OWNED) {
+        Py_DECREF(((CDataObject_own_structptr *)cd)->structobj);
     }
-    else if (cdb->head.c_type->ct_flags & CT_FUNCTIONPTR) {
+    else if (cd->c_type->ct_flags & CT_FUNCTIONPTR) {
         /* a callback */
-        ffi_closure *closure = (ffi_closure *)cdb->head.c_data;
+        ffi_closure *closure = (ffi_closure *)cd->c_data;
         PyObject *args = (PyObject *)(closure->user_data);
         Py_XDECREF(args);
         cffi_closure_free(closure);
     }
-    cdata_dealloc(&cdb->head);
+    cdata_dealloc(cd);
 }
 
 static int cdata_traverse(CDataObject *cd, visitproc visit, void *arg)
@@ -1918,7 +1915,7 @@
     (traverseproc)cdata_traverse,               /* tp_traverse */
     0,                                          /* tp_clear */
     cdata_richcompare,                          /* tp_richcompare */
-    0,                                          /* tp_weaklistoffset */
+    offsetof(CDataObject, c_weakreflist),       /* tp_weaklistoffset */
     (getiterfunc)cdata_iter,                    /* tp_iter */
     0,                                          /* tp_iternext */
 };
@@ -1926,7 +1923,7 @@
 static PyTypeObject CDataOwning_Type = {
     PyVarObject_HEAD_INIT(NULL, 0)
     "_cffi_backend.CDataOwn",
-    sizeof(CDataObject_own_base),
+    sizeof(CDataObject),
     0,
     (destructor)cdataowning_dealloc,            /* tp_dealloc */
     0,                                          /* tp_print */
@@ -1948,7 +1945,7 @@
     0,                                          /* tp_traverse */
     0,                                          /* tp_clear */
     0,                                          /* tp_richcompare */
-    offsetof(CDataObject_own_base, weakreflist),/* tp_weaklistoffset */
+    0,                                          /* tp_weaklistoffset */
     0,                                          /* tp_iter */
     0,                                          /* tp_iternext */
     0,                                          /* tp_methods */
@@ -2040,24 +2037,24 @@
 
 /************************************************************/
 
-static CDataObject_own_base *allocate_owning_object(Py_ssize_t size,
-                                                    CTypeDescrObject *ct)
+static CDataObject *allocate_owning_object(Py_ssize_t size,
+                                           CTypeDescrObject *ct)
 {
-    CDataObject_own_base *cdb;
-    cdb = (CDataObject_own_base *)PyObject_Malloc(size);
-    if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
+    CDataObject *cd;
+    cd = (CDataObject *)PyObject_Malloc(size);
+    if (PyObject_Init((PyObject *)cd, &CDataOwning_Type) == NULL)
         return NULL;
 
     Py_INCREF(ct);
-    cdb->head.c_type = ct;
-    cdb->weakreflist = NULL;
-    return cdb;
+    cd->c_type = ct;
+    cd->c_weakreflist = NULL;
+    return cd;
 }
 
 static PyObject *
 convert_struct_to_owning_object(char *data, CTypeDescrObject *ct)
 {
-    CDataObject_own_base *cdb;
+    CDataObject *cd;
     Py_ssize_t dataoffset = offsetof(CDataObject_own_nolength, alignment);
     Py_ssize_t datasize = ct->ct_size;
 
@@ -2066,20 +2063,19 @@
                         "return type is not a struct or is opaque");
         return NULL;
     }
-    cdb = allocate_owning_object(dataoffset + datasize, ct);
-    if (cdb == NULL)
+    cd = allocate_owning_object(dataoffset + datasize, ct);
+    if (cd == NULL)
         return NULL;
-    cdb->head.c_data = ((char *)cdb) + dataoffset;
-
-    memcpy(cdb->head.c_data, data, datasize);
-    return (PyObject *)cdb;
+    cd->c_data = ((char *)cd) + dataoffset;
+
+    memcpy(cd->c_data, data, datasize);
+    return (PyObject *)cd;
 }
 
 static PyObject *b_newp(PyObject *self, PyObject *args)
 {
     CTypeDescrObject *ct, *ctitem;
     CDataObject *cd;
-    CDataObject_own_base *cdb;
     PyObject *init = Py_None;
     Py_ssize_t dataoffset, datasize, explicitlength;
     if (!PyArg_ParseTuple(args, "O!|O:newp", &CTypeDescr_Type, &ct, &init))
@@ -2147,33 +2143,31 @@
            we build two objects instead of one, with the memory-owning
            one being really the struct (or union) and the returned one
            having a strong reference to it */
-        CDataObject_own_base *cdp;
-
-        cdb = allocate_owning_object(dataoffset + datasize, ct->ct_itemdescr);
-        if (cdb == NULL)
+        CDataObject *cds;
+
+        cds = allocate_owning_object(dataoffset + datasize, ct->ct_itemdescr);
+        if (cds == NULL)
             return NULL;
 
-        cdp = allocate_owning_object(sizeof(CDataObject_own_structptr), ct);
-        if (cdp == NULL) {
-            Py_DECREF(cdb);
+        cd = allocate_owning_object(sizeof(CDataObject_own_structptr), ct);
+        if (cd == NULL) {
+            Py_DECREF(cds);
             return NULL;
         }
-        /* store the only reference to cdb into cdp */
-        ((CDataObject_own_structptr *)cdp)->structobj = (PyObject *)cdb;
+        /* store the only reference to cds into cd */
+        ((CDataObject_own_structptr *)cd)->structobj = (PyObject *)cds;
         assert(explicitlength < 0);
 
-        cdb->head.c_data = cdp->head.c_data = ((char *)cdb) + dataoffset;
-        cd = &cdp->head;
+        cds->c_data = cd->c_data = ((char *)cds) + dataoffset;
     }
     else {
-        cdb = allocate_owning_object(dataoffset + datasize, ct);
-        if (cdb == NULL)
+        cd = allocate_owning_object(dataoffset + datasize, ct);
+        if (cd == NULL)
             return NULL;
 
-        cdb->head.c_data = ((char *)cdb) + dataoffset;
+        cd->c_data = ((char *)cd) + dataoffset;
         if (explicitlength >= 0)
-            ((CDataObject_own_length*)cdb)->length = explicitlength;
-        cd = &cdb->head;
+            ((CDataObject_own_length*)cd)->length = explicitlength;
     }
 
     memset(cd->c_data, 0, datasize);
@@ -2196,6 +2190,7 @@
     Py_INCREF(ct);
     cd->c_type = ct;
     cd->c_data = ((char*)cd) + dataoffset;
+    cd->c_weakreflist = NULL;
     return cd;
 }
 
@@ -3571,7 +3566,7 @@
 static PyObject *b_callback(PyObject *self, PyObject *args)
 {
     CTypeDescrObject *ct, *ctresult;
-    CDataObject_own_base *cdb;
+    CDataObject *cd;
     PyObject *ob, *error_ob = Py_None;
     PyObject *py_rawerr, *infotuple = NULL;
     cif_description_t *cif_descr;
@@ -3616,13 +3611,13 @@
 
     closure = cffi_closure_alloc();
 
-    cdb = PyObject_New(CDataObject_own_base, &CDataOwning_Type);
-    if (cdb == NULL)
+    cd = PyObject_New(CDataObject, &CDataOwning_Type);
+    if (cd == NULL)
         goto error;
     Py_INCREF(ct);
-    cdb->head.c_type = ct;
-    cdb->head.c_data = (char *)closure;
-    cdb->weakreflist = NULL;
+    cd->c_type = ct;
+    cd->c_data = (char *)closure;
+    cd->c_weakreflist = NULL;
 
     cif_descr = (cif_description_t *)ct->ct_extra;
     if (cif_descr == NULL) {
@@ -3637,14 +3632,14 @@
         goto error;
     }
     assert(closure->user_data == infotuple);
-    return (PyObject *)cdb;
+    return (PyObject *)cd;
 
  error:
     closure->user_data = NULL;
-    if (cdb == NULL)
+    if (cd == NULL)
         cffi_closure_free(closure);
     else
-        Py_DECREF(cdb);
+        Py_DECREF(cd);
     Py_XDECREF(infotuple);
     return NULL;
 }
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1147,8 +1147,8 @@
     BPtr = new_pointer_type(BInt)
     weakref.ref(BInt)
     weakref.ref(newp(BPtr, 42))
-    py.test.raises(TypeError, weakref.ref, cast(BPtr, 42))
-    py.test.raises(TypeError, weakref.ref, cast(BInt, 42))
+    weakref.ref(cast(BPtr, 42))
+    weakref.ref(cast(BInt, 42))
 
 def test_no_inheritance():
     BInt = new_primitive_type("int")


More information about the pypy-commit mailing list