[pypy-commit] cffi default: hg backout 0ed9b03dd40d, f0cdef5768b5, 95c88bfbf9f7.

arigo noreply at buildbot.pypy.org
Fri Jun 29 10:49:58 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r559:ae0b6ba4b07b
Date: 2012-06-29 09:10 +0200
http://bitbucket.org/cffi/cffi/changeset/ae0b6ba4b07b/

Log:	hg backout 0ed9b03dd40d, f0cdef5768b5, 95c88bfbf9f7.

	Will redo struct-returning functions slightly differently.

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -22,11 +22,6 @@
 # define USE__THREAD
 #endif
 
-/* Define CAN_RETURN_STRUCTS if the C compiler supports returning structs */
-#if !defined(MS_WIN32)
-# define CAN_RETURN_STRUCTS
-#endif
-
 /************************************************************/
 
 /* base type flag: exactly one of the following: */
@@ -1425,9 +1420,6 @@
     return PyObject_GenericSetAttr((PyObject *)cd, attr, value);
 }
 
-static PyObject *
-convert_struct_to_owning_object(char *data, CTypeDescrObject *ct); /*forward*/
-
 static cif_description_t *
 fb_prepare_cif(PyObject *fargs, CTypeDescrObject *fresult);    /* forward */
 
@@ -1550,9 +1542,6 @@
         res = Py_None;
         Py_INCREF(res);
     }
-    else if (fresult->ct_flags & CT_STRUCT) {
-        res = convert_struct_to_owning_object(resultdata, fresult);
-    }
     else {
         res = convert_to_object(resultdata, fresult);
     }
@@ -1760,46 +1749,10 @@
 
 /************************************************************/
 
-static CDataObject *allocate_owning_object(Py_ssize_t dataoffset,
-                                           Py_ssize_t datasize,
-                                           CTypeDescrObject *ct)
-{
-    CDataObject_own_base *cdb;
-    cdb = (CDataObject_own_base *)PyObject_Malloc(dataoffset + datasize);
-    if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
-        return NULL;
-
-    Py_INCREF(ct);
-    cdb->head.c_type = ct;
-    cdb->head.c_data = ((char *)cdb) + dataoffset;
-    cdb->weakreflist = NULL;
-    return &cdb->head;
-}
-
-static PyObject *
-convert_struct_to_owning_object(char *data, CTypeDescrObject *ct)
-{
-    CDataObject *cd;
-    Py_ssize_t dataoffset = offsetof(CDataObject_own_nolength, alignment);
-    Py_ssize_t datasize = ct->ct_size;
-
-    if ((ct->ct_flags & (CT_STRUCT|CT_IS_OPAQUE)) != CT_STRUCT) {
-        PyErr_SetString(PyExc_TypeError,
-                        "return type is not a struct or is opaque");
-        return NULL;
-    }
-    cd = allocate_owning_object(dataoffset, datasize, ct);
-    if (cd == NULL)
-        return NULL;
-
-    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))
@@ -1856,21 +1809,26 @@
         return NULL;
     }
 
-    cd = allocate_owning_object(dataoffset, datasize, ct);
-    if (cd == NULL)
+    cdb = (CDataObject_own_base *)PyObject_Malloc(dataoffset + datasize);
+    if (PyObject_Init((PyObject *)cdb, &CDataOwning_Type) == NULL)
         return NULL;
+
+    Py_INCREF(ct);
+    cdb->head.c_type = ct;
+    cdb->head.c_data = ((char *)cdb) + dataoffset;
+    cdb->weakreflist = NULL;
     if (explicitlength >= 0)
-        ((CDataObject_own_length*)cd)->length = explicitlength;
-
-    memset(cd->c_data, 0, datasize);
+        ((CDataObject_own_length*)cdb)->length = explicitlength;
+
+    memset(cdb->head.c_data, 0, datasize);
     if (init != Py_None) {
-        if (convert_from_object(cd->c_data,
+        if (convert_from_object(cdb->head.c_data,
               (ct->ct_flags & CT_POINTER) ? ct->ct_itemdescr : ct, init) < 0) {
-            Py_DECREF(cd);
+            Py_DECREF(cdb);
             return NULL;
         }
     }
-    return (PyObject *)cd;
+    return (PyObject *)cdb;
 }
 
 static CDataObject *_new_casted_primitive(CTypeDescrObject *ct)
@@ -2785,14 +2743,11 @@
     if (PyErr_Occurred())
         return -1;
     if (cif_descr != NULL) {
-#ifndef CAN_RETURN_STRUCTS
         if (fb->rtype->type == FFI_TYPE_STRUCT) {
             PyErr_SetString(PyExc_NotImplementedError,
-                            "functions returning structs are not supported "
-                            "on this platform");
+                            "functions returning structs are not supported");
             return -1;
         }
-#endif
         /* exchange data size */
         /* first, enough room for an array of 'nargs' pointers */
         exchange_offset = nargs * sizeof(void*);
@@ -2990,9 +2945,9 @@
                           &ellipsis))
         return NULL;
 
-    if (fresult->ct_flags & CT_UNION) {
+    if (fresult->ct_flags & (CT_STRUCT|CT_UNION)) {
         PyErr_SetString(PyExc_NotImplementedError,
-                        "functions returning a union");
+                        "functions returning a struct or a union");
         return NULL;
     }
     if ((fresult->ct_size < 0 && !(fresult->ct_flags & CT_VOID)) ||
@@ -3465,16 +3420,6 @@
     return total;
 }
 
-#ifdef CAN_RETURN_STRUCTS
-static struct _testfunc7_s _testfunc10(int n)
-{
-    struct _testfunc7_s result;
-    result.a1 = n;
-    result.a2 = n * n;
-    return result;
-}
-#endif
-
 static PyObject *b__testfunc(PyObject *self, PyObject *args)
 {
     /* for testing only */
@@ -3493,9 +3438,6 @@
     case 7: f = &_testfunc7; break;
     case 8: f = stderr; break;
     case 9: f = &_testfunc9; break;
-#ifdef CAN_RETURN_STRUCTS
-    case 10: f = &_testfunc10; break;
-#endif
     default:
         PyErr_SetNone(PyExc_ValueError);
         return NULL;
@@ -3648,7 +3590,6 @@
     _cffi_from_c_char,
     convert_to_object,
     convert_from_object,
-    convert_struct_to_owning_object,
 };
 
 /************************************************************/
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1140,32 +1140,18 @@
     p.a1 = ['x', 'y']
     assert str(p.a1) == 'xyo'
 
-def test_invalid_function_result_types():
+def test_no_struct_return_in_func():
     BFunc = new_function_type((), new_void_type())
     BArray = new_array_type(new_pointer_type(BFunc), 5)        # works
     new_function_type((), BFunc)    # works
     new_function_type((), new_primitive_type("int"))
     new_function_type((), new_pointer_type(BFunc))
-    py.test.raises(NotImplementedError, new_function_type,
-                   (), new_union_type("foo_u"))
+    py.test.raises(NotImplementedError, new_function_type, (),
+                   new_struct_type("foo_s"))
+    py.test.raises(NotImplementedError, new_function_type, (),
+                   new_union_type("foo_u"))
     py.test.raises(TypeError, new_function_type, (), BArray)
 
-def test_struct_return_in_func():
-    if sys.platform == 'win32':
-        py.test.skip("function returning struct")
-    BChar = new_primitive_type("char")
-    BShort = new_primitive_type("short")
-    BInt = new_primitive_type("int")
-    BStruct = new_struct_type("foo_s")
-    complete_struct_or_union(BStruct, [('a1', BChar, -1),
-                                       ('a2', BShort, -1)])
-    BFunc10 = new_function_type((BInt,), BStruct)
-    f = cast(BFunc10, _testfunc(10))
-    s = f(40)
-    assert repr(s) == "<cdata 'struct foo_s' owning 4 bytes>"
-    assert s.a1 == chr(40)
-    assert s.a2 == 40 * 40
-
 def test_cast_with_functionptr():
     BFunc = new_function_type((), new_void_type())
     BFunc2 = new_function_type((), new_primitive_type("short"))
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -184,9 +184,6 @@
         elif isinstance(tp, model.ArrayType):
             return '_cffi_from_c_deref((char *)%s, _cffi_type(%d))' % (
                 var, self.gettypenum(tp))
-        elif isinstance(tp, model.StructType):
-            return '_cffi_from_c_struct((char *)&%s, _cffi_type(%d))' % (
-                var, self.gettypenum(tp))
         else:
             raise NotImplementedError(tp)
 
@@ -617,9 +614,7 @@
     ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[16])
 #define _cffi_to_c                                                       \
     ((int(*)(char *, CTypeDescrObject *, PyObject *))_cffi_exports[17])
-#define _cffi_from_c_struct                                              \
-    ((PyObject *(*)(char *, CTypeDescrObject *))_cffi_exports[18])
-#define _CFFI_NUM_EXPORTS 19
+#define _CFFI_NUM_EXPORTS 18
 
 #if SIZEOF_LONG < SIZEOF_LONG_LONG
 #  define _cffi_to_c_long_long PyLong_AsLongLong
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -576,27 +576,3 @@
     """)
     msg = 'cannot pass as a argument a struct that was completed with verify()'
     assert msg in str(e.value)
-
-def test_func_returns_struct():
-    # only supported via verify(), when GCC is the compiler; and only for
-    # regular functions.
-    ffi = FFI()
-    ffi.cdef("""
-        struct foo_s { int aa, bb; };
-        struct foo_s foo(int a, int b);
-    """)
-    lib = ffi.verify("""
-        struct foo_s { int aa, bb; };
-        struct foo_s foo(int a, int b) {
-            struct foo_s r;
-            r.aa = a*a;
-            r.bb = b*b;
-            return r;
-        }
-    """)
-    s = lib.foo(6, 7)
-    # It's the only way to have a 'struct foo_s' that owns its memory.
-    # With ffi.new() we always get a 'struct foo_s *' that owns the memory.
-    assert repr(s) == "<cdata 'struct foo_s' owning 8 bytes>"
-    assert s.aa == 36
-    assert s.bb == 49


More information about the pypy-commit mailing list