Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r200:5e92a110871a
Date: 2014-12-13 22:59 +0000
http://bitbucket.org/cffi/creflect/changeset/5e92a110871a/

Log:    test and fix for functions returning structs

diff --git a/zeffir/cfunc.c b/zeffir/cfunc.c
--- a/zeffir/cfunc.c
+++ b/zeffir/cfunc.c
@@ -160,10 +160,11 @@
     void *llargs[nargs];
     char *llbuffer;
     size_t lloffset;
-    int i, returns_void;
+    int i, returns_void, returns_spec;
 
     llbuffer = alloca(zfs->zfs_size_args);
     returns_void = (zfs->zfs_ret->ct_flags & CT_VOID);
+    returns_spec = (zfs->zfs_ret->ct_flags & (CT_VOID | CT_STRUCT | CT_UNION));
     lloffset = returns_void ? 0 : zfs->zfs_ret->ct_size;
 
     for (i = 0; i < nargs; i++) {
@@ -208,9 +209,21 @@
         ((_crx_trampoline1_fn)zfs->zfs_trampl)(func, llargs, llbuffer);
     }
 
-    if (returns_void) {
-        Py_INCREF(Py_None);
-        return Py_None;
+    if (returns_spec) {
+        if (returns_void) {
+            Py_INCREF(Py_None);
+            return Py_None;
+        }
+        Py_ssize_t dataoffset = offsetof(CDataObject_own_nolength, alignment);
+        Py_ssize_t datasize = zfs->zfs_ret->ct_size;
+        CDataObject *cd;
+
+        cd = allocate_owning_object(dataoffset + datasize, zfs->zfs_ret);
+        if (cd == NULL)
+            return NULL;
+        cd->c_data = ((char *)cd) + dataoffset;
+        memcpy(cd->c_data, llbuffer, datasize);
+        return (PyObject *)cd;
     }
     return convert_to_object(llbuffer, zfs->zfs_ret);
 }
diff --git a/zeffir/test/struct.crx b/zeffir/test/struct.crx
--- a/zeffir/test/struct.crx
+++ b/zeffir/test/struct.crx
@@ -9,6 +9,13 @@
     int baz[];
 } myarrstr_t;
 
+mystruct_t swap(mystruct_t x) {
+    long v = x.b;
+    x.b = x.a;
+    x.a = v;
+    return x;
+}
+
 
 // CREFLECT: start
 
@@ -22,4 +29,6 @@
     int baz[];
 } myarrstr_t;
 
+mystruct_t swap(mystruct_t);
+
 // CREFLECT: end
diff --git a/zeffir/test/test_struct.py b/zeffir/test/test_struct.py
--- a/zeffir/test/test_struct.py
+++ b/zeffir/test/test_struct.py
@@ -54,3 +54,15 @@
     s.b += 1
     assert s.b == 0x600112234
     assert ffi.addressof(s)[0] == s
+    assert ffi.typeof(s) == ffi.typeof("mystruct_t")
+
+def test_func_with_struct_arg_and_result():
+    ffi, lib = support.compile_and_open('struct')
+    s1 = ffi.new("mystruct_t", [-5, 0x600112233])
+    s2 = lib.swap(s1)
+    assert ffi.typeof(s2) == ffi.typeof("mystruct_t")
+    assert (s1.a, s1.b) == (-5, 0x600112233)
+    assert (s2.a, s2.b) == (0x112233, -5)
+    s3 = lib.swap(s2)
+    assert (s2.a, s2.b) == (0x112233, -5)
+    assert (s3.a, s3.b) == (-5, 0x112233)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to