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