Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r2497:f52d1e25624c
Date: 2015-12-24 11:14 +0100
http://bitbucket.org/cffi/cffi/changeset/f52d1e25624c/

Log:    Clarify a little bit 'cffi_allocator_t'. Motivation: obscure gcc bug
        (issue #240)

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -279,8 +279,11 @@
 # include "wchar_helper.h"
 #endif
 
-typedef PyObject *const cffi_allocator_t[3];
-static cffi_allocator_t default_allocator = { NULL, NULL, NULL };
+typedef struct _cffi_allocator_s {
+    PyObject *ca_alloc, *ca_free;
+    int ca_dont_clear;
+} cffi_allocator_t;
+static const cffi_allocator_t default_allocator = { NULL, NULL, 0 };
 static PyObject *FFIError;
 static PyObject *unique_cache;
 
@@ -3019,21 +3022,18 @@
 static CDataObject *allocate_with_allocator(Py_ssize_t basesize,
                                             Py_ssize_t datasize,
                                             CTypeDescrObject *ct,
-                                            cffi_allocator_t allocator)
+                                            const cffi_allocator_t *allocator)
 {
     CDataObject *cd;
-    PyObject *my_alloc = allocator[0];
-    PyObject *my_free = allocator[1];
-    PyObject *dont_clear_after_alloc = allocator[2];
-
-    if (my_alloc == NULL) {   /* alloc */
+
+    if (allocator->ca_alloc == NULL) {
         cd = allocate_owning_object(basesize + datasize, ct);
         if (cd == NULL)
             return NULL;
         cd->c_data = ((char *)cd) + basesize;
     }
     else {
-        PyObject *res = PyObject_CallFunction(my_alloc, "n", datasize);
+        PyObject *res = PyObject_CallFunction(allocator->ca_alloc, "n", 
datasize);
         if (res == NULL)
             return NULL;
 
@@ -3058,16 +3058,16 @@
             return NULL;
         }
 
-        cd = allocate_gcp_object(cd, ct, my_free);
+        cd = allocate_gcp_object(cd, ct, allocator->ca_free);
         Py_DECREF(res);
     }
-    if (dont_clear_after_alloc == NULL)
+    if (!allocator->ca_dont_clear)
         memset(cd->c_data, 0, datasize);
     return cd;
 }
 
 static PyObject *direct_newp(CTypeDescrObject *ct, PyObject *init,
-                             cffi_allocator_t allocator)
+                             const cffi_allocator_t *allocator)
 {
     CTypeDescrObject *ctitem;
     CDataObject *cd;
@@ -3172,7 +3172,7 @@
     PyObject *init = Py_None;
     if (!PyArg_ParseTuple(args, "O!|O:newp", &CTypeDescr_Type, &ct, &init))
         return NULL;
-    return direct_newp(ct, init, default_allocator);
+    return direct_newp(ct, init, &default_allocator);
 }
 
 static int
diff --git a/c/ffi_obj.c b/c/ffi_obj.c
--- a/c/ffi_obj.c
+++ b/c/ffi_obj.c
@@ -335,7 +335,7 @@
 "pointer to the memory somewhere else, e.g. into another structure.");
 
 static PyObject *_ffi_new(FFIObject *self, PyObject *args, PyObject *kwds,
-                          cffi_allocator_t allocator)
+                          const cffi_allocator_t *allocator)
 {
     CTypeDescrObject *ct;
     PyObject *arg, *init = Py_None;
@@ -353,15 +353,22 @@
 
 static PyObject *ffi_new(FFIObject *self, PyObject *args, PyObject *kwds)
 {
-    return _ffi_new(self, args, kwds, default_allocator);
+    return _ffi_new(self, args, kwds, &default_allocator);
 }
 
 static PyObject *_ffi_new_with_allocator(PyObject *allocator, PyObject *args,
                                          PyObject *kwds)
 {
+    cffi_allocator_t alloc1;
+    PyObject *my_alloc, *my_free;
+    my_alloc = PyTuple_GET_ITEM(allocator, 1);
+    my_free  = PyTuple_GET_ITEM(allocator, 2);
+    alloc1.ca_alloc = (my_alloc == Py_None ? NULL : my_alloc);
+    alloc1.ca_free  = (my_free  == Py_None ? NULL : my_free);
+    alloc1.ca_dont_clear = (PyTuple_GET_ITEM(allocator, 3) == Py_False);
+
     return _ffi_new((FFIObject *)PyTuple_GET_ITEM(allocator, 0),
-                    args, kwds,
-                    &PyTuple_GET_ITEM(allocator, 1));
+                    args, kwds, &alloc1);
 }
 
 PyDoc_STRVAR(ffi_new_allocator_doc,
@@ -396,27 +403,14 @@
         return NULL;
     }
 
-    allocator = PyTuple_New(4);
+    allocator = PyTuple_Pack(4,
+                             (PyObject *)self,
+                             my_alloc,
+                             my_free,
+                             PyBool_FromLong(should_clear_after_alloc));
     if (allocator == NULL)
         return NULL;
 
-    Py_INCREF(self);
-    PyTuple_SET_ITEM(allocator, 0, (PyObject *)self);
-
-    if (my_alloc != Py_None) {
-        Py_INCREF(my_alloc);
-        PyTuple_SET_ITEM(allocator, 1, my_alloc);
-    }
-    if (my_free != Py_None) {
-        Py_INCREF(my_free);
-        PyTuple_SET_ITEM(allocator, 2, my_free);
-    }
-    if (!should_clear_after_alloc) {
-        PyObject *my_true = Py_True;
-        Py_INCREF(my_true);
-        PyTuple_SET_ITEM(allocator, 3, my_true);  /* dont_clear_after_alloc */
-    }
-
     {
         static PyMethodDef md = {"allocator",
                                  (PyCFunction)_ffi_new_with_allocator,
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to