[pypy-svn] pypy jitypes2: teach _ffi how to deal with structures by value: now you must pass directly

antocuni commits-noreply at bitbucket.org
Wed Jan 12 17:52:06 CET 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: jitypes2
Changeset: r40629:7b74c1c21f9f
Date: 2011-01-12 17:24 +0100
http://bitbucket.org/pypy/pypy/changeset/7b74c1c21f9f/

Log:	teach _ffi how to deal with structures by value: now you must pass
	directly the _rawffi.structure.W_StructureInstance object instead of
	the memory address where it resides; similarly, W_StructureInstance
	objects are returned instead of returning the memory address

diff --git a/pypy/module/_ffi/test/test__ffi.py b/pypy/module/_ffi/test/test__ffi.py
--- a/pypy/module/_ffi/test/test__ffi.py
+++ b/pypy/module/_ffi/test/test__ffi.py
@@ -265,7 +265,7 @@
         p = POINT()
         p.x = 30
         p.y = 12
-        res = sum_point(p.buffer)
+        res = sum_point(p)
         assert res == 42
         p.free()
 
@@ -285,8 +285,7 @@
         libfoo = CDLL(self.libfoo_name)
         make_point = libfoo.getfunc('make_point', [types.slong, types.slong], ffi_point)
         #
-        adr = make_point(12, 34)
-        p = POINT.fromaddress(adr)
+        p = make_point(12, 34)
         assert p.x == 12
         assert p.y == 34
         p.free()

diff --git a/pypy/module/_rawffi/interp_rawffi.py b/pypy/module/_rawffi/interp_rawffi.py
--- a/pypy/module/_rawffi/interp_rawffi.py
+++ b/pypy/module/_rawffi/interp_rawffi.py
@@ -252,7 +252,7 @@
         # term, probably we will move the code for build structures and arrays
         # from _rawffi to _ffi
         from pypy.module._ffi.interp_ffi import W_FFIType
-        return W_FFIType('<name>', '1', self.get_basic_ffi_type())
+        return W_FFIType('<name>', '1', self.get_basic_ffi_type(), self)
 
     def descr_size_alignment(self, space, n=1):
         return space.newtuple([space.wrap(self.size * n),

diff --git a/pypy/module/_ffi/interp_ffi.py b/pypy/module/_ffi/interp_ffi.py
--- a/pypy/module/_ffi/interp_ffi.py
+++ b/pypy/module/_ffi/interp_ffi.py
@@ -5,6 +5,7 @@
     operationerrfmt
 from pypy.interpreter.gateway import interp2app, NoneNotWrapped, unwrap_spec
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
+from pypy.module._rawffi.structure import W_StructureInstance, W_Structure
 #
 from pypy.rpython.lltypesystem import lltype, rffi
 #
@@ -14,10 +15,13 @@
 from pypy.rlib.rarithmetic import intmask, r_uint
 
 class W_FFIType(Wrappable):
-    def __init__(self, name, shape, ffitype):
+    def __init__(self, name, shape, ffitype, w_datashape=None):
         self.name = name
         self.shape = shape
         self.ffitype = ffitype
+        self.w_datashape = w_datashape
+        if self.is_struct():
+            assert w_datashape is not None
 
     @unwrap_spec('self', ObjSpace)
     def str(self, space):
@@ -150,8 +154,8 @@
                 argchain.arg_singlefloat(space.float_w(w_arg))
             elif w_argtype.is_struct():
                 # arg_raw directly takes value to put inside ll_args
-                uintval = space.uint_w(w_arg)
-                ptrval = rffi.cast(rffi.VOIDP, uintval)
+                w_arg = space.interp_w(W_StructureInstance, w_arg)                
+                ptrval = w_arg.ll_buffer
                 argchain.arg_raw(ptrval)
             else:
                 assert False, "Argument shape '%s' not supported" % w_argtype.shape
@@ -195,8 +199,10 @@
             floatres = self.func.call(argchain, rffi.FLOAT)
             return space.wrap(floatres)
         elif w_restype.is_struct():
-            # we return the address of the buffer as an integer
-            return self._call_uint(space, argchain)
+            w_datashape = w_restype.w_datashape
+            assert isinstance(w_datashape, W_Structure)
+            ptrval = self.func.call(argchain, rffi.VOIDP, is_struct=True)
+            return w_datashape.fromaddress(space, ptrval)
         elif w_restype.is_void():
             voidres = self.func.call(argchain, lltype.Void)
             assert voidres is None
@@ -249,10 +255,6 @@
             ptrres = call(argchain, rffi.VOIDP)
             uintres = rffi.cast(rffi.ULONG, ptrres)
             return space.wrap(uintres)
-        elif libffi.types.is_struct(restype):
-            ptrres = call(argchain, rffi.VOIDP, is_struct=True)
-            uintres = rffi.cast(rffi.ULONG, ptrres)
-            return space.wrap(uintres)
         elif restype is libffi.types.uint:
             intres = rffi.cast(rffi.LONG, call(argchain, rffi.UINT))
         elif restype is libffi.types.ushort:


More information about the Pypy-commit mailing list