[pypy-svn] pypy jitypes2: support struct by value as return type
antocuni
commits-noreply at bitbucket.org
Thu Dec 23 17:34:55 CET 2010
Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: jitypes2
Changeset: r40212:1e6f3d9f7e72
Date: 2010-12-23 17:26 +0100
http://bitbucket.org/pypy/pypy/changeset/1e6f3d9f7e72/
Log: support struct by value as return type
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -406,7 +406,13 @@
rffi.cast(rffi.VOIDPP, ll_args))
if RESULT is not lltype.Void:
TP = lltype.Ptr(rffi.CArray(RESULT))
- res = rffi.cast(TP, ll_result)[0]
+ buf = rffi.cast(TP, ll_result)
+ if self.restype.c_type == FFI_TYPE_STRUCT:
+ # for structs, we directly return the buffer and transfer the
+ # ownership
+ res = rffi.cast(RESULT, buf)
+ else:
+ res = buf[0]
else:
res = None
self._free_buffers(ll_result, ll_args)
@@ -414,7 +420,9 @@
return res
def _free_buffers(self, ll_result, ll_args):
- if ll_result:
+ if ll_result and self.restype.c_type != FFI_TYPE_STRUCT:
+ # if it's a struct, the buffer is not freed and the ownership is
+ # transferred to the caller
lltype.free(ll_result, flavor='raw')
for i in range(len(self.argtypes)):
lltype.free(ll_args[i], flavor='raw')
diff --git a/pypy/rlib/test/test_libffi.py b/pypy/rlib/test/test_libffi.py
--- a/pypy/rlib/test/test_libffi.py
+++ b/pypy/rlib/test/test_libffi.py
@@ -407,3 +407,26 @@
res = self.call(func, [('arg_raw', adr)], rffi.LONG, init_result=0)
assert res == 42
lltype.free(ffi_point_struct, flavor='raw')
+
+ def test_byval_result(self):
+ """
+ struct Point make_point(long x, long y) {
+ struct Point p;
+ p.x = x;
+ p.y = y;
+ return p;
+ }
+ """
+ libfoo = CDLL(self.libfoo_name)
+ ffi_point_struct = make_struct_ffitype_e(0, 0, [types.slong, types.slong])
+ ffi_point = ffi_point_struct.ffistruct
+
+ libfoo = CDLL(self.libfoo_name)
+ make_point = (libfoo, 'make_point', [types.slong, types.slong], ffi_point)
+ #
+ PTR = lltype.Ptr(rffi.CArray(rffi.LONG))
+ p = self.call(make_point, [12, 34], PTR, init_result=0)
+ assert p[0] == 12
+ assert p[1] == 34
+ lltype.free(p, flavor='raw')
+ lltype.free(ffi_point_struct, flavor='raw')
More information about the Pypy-commit
mailing list