Author: Antonio Cuni <[email protected]>
Branch: ffistruct
Changeset: r55119:15f1a0ac245f
Date: 2012-05-17 09:24 +0200
http://bitbucket.org/pypy/pypy/changeset/15f1a0ac245f/

Log:    temporarly re-add support for _rawffi structures. This way, it
        should be possible to merge the branch without breaking ctypes. In
        the longterm, the plan is to implement ctypes.Structure on top of
        _ffi._StructDescr

diff --git a/pypy/module/_ffi/interp_funcptr.py 
b/pypy/module/_ffi/interp_funcptr.py
--- a/pypy/module/_ffi/interp_funcptr.py
+++ b/pypy/module/_ffi/interp_funcptr.py
@@ -129,6 +129,11 @@
         ptrval = w_structinstance.rawmem
         self.argchain.arg_raw(ptrval)
 
+    def handle_struct_rawffi(self, w_ffitype, w_structinstance):
+        # arg_raw directly takes value to put inside ll_args
+        ptrval = w_structinstance.ll_buffer
+        self.argchain.arg_raw(ptrval)
+
 
 class CallFunctionConverter(ToAppLevelConverter):
     """
@@ -208,6 +213,10 @@
         addr = self.func.call(self.argchain, rffi.LONG, is_struct=True)
         return w_structdescr.fromaddress(self.space, addr)
 
+    def get_struct_rawffi(self, w_ffitype, w_structdescr):
+        uintval = self.func.call(self.argchain, rffi.ULONG, is_struct=True)
+        return w_structdescr.fromaddress(self.space, uintval)
+
     def get_void(self, w_ffitype):
         return self.func.call(self.argchain, lltype.Void)
     
diff --git a/pypy/module/_ffi/test/test_funcptr.py 
b/pypy/module/_ffi/test/test_funcptr.py
--- a/pypy/module/_ffi/test/test_funcptr.py
+++ b/pypy/module/_ffi/test/test_funcptr.py
@@ -488,6 +488,47 @@
         assert p.getfield('x') == 12
         assert p.getfield('y') == 34
 
+    # XXX: support for _rawffi structures should be killed as soon as we
+    # implement ctypes.Structure on top of _ffi. In the meantime, we support
+    # both
+    def test_byval_argument__rawffi(self):
+        """
+            // defined above
+            struct Point;
+            DLLEXPORT long sum_point(struct Point p);
+        """
+        import _rawffi
+        from _ffi import CDLL, types
+        POINT = _rawffi.Structure([('x', 'l'), ('y', 'l')])
+        ffi_point = POINT.get_ffi_type()
+        libfoo = CDLL(self.libfoo_name)
+        sum_point = libfoo.getfunc('sum_point', [ffi_point], types.slong)
+        #
+        p = POINT()
+        p.x = 30
+        p.y = 12
+        res = sum_point(p)
+        assert res == 42
+        p.free()
+
+    def test_byval_result__rawffi(self):
+        """
+            // defined above
+            DLLEXPORT struct Point make_point(long x, long y);
+        """
+        import _rawffi
+        from _ffi import CDLL, types
+        POINT = _rawffi.Structure([('x', 'l'), ('y', 'l')])
+        ffi_point = POINT.get_ffi_type()
+        libfoo = CDLL(self.libfoo_name)
+        make_point = libfoo.getfunc('make_point', [types.slong, types.slong], 
ffi_point)
+        #
+        p = make_point(12, 34)
+        assert p.x == 12
+        assert p.y == 34
+        p.free()
+
+
     def test_TypeError_numargs(self):
         from _ffi import CDLL, types
         libfoo = CDLL(self.libfoo_name)
diff --git a/pypy/module/_ffi/type_converter.py 
b/pypy/module/_ffi/type_converter.py
--- a/pypy/module/_ffi/type_converter.py
+++ b/pypy/module/_ffi/type_converter.py
@@ -3,6 +3,7 @@
 from pypy.rlib.rarithmetic import intmask, r_uint
 from pypy.rpython.lltypesystem import rffi
 from pypy.interpreter.error import operationerrfmt
+from pypy.module._rawffi.structure import W_StructureInstance, W_Structure
 from pypy.module._ffi.interp_ffitype import app_types
 
 class FromAppLevelConverter(object):
@@ -49,8 +50,11 @@
         elif w_ffitype.is_singlefloat():
             self._singlefloat(w_ffitype, w_obj)
         elif w_ffitype.is_struct():
-            w_obj = space.interp_w(W__StructInstance, w_obj)
-            self.handle_struct(w_ffitype, w_obj)
+            if isinstance(w_obj, W_StructureInstance):
+                self.handle_struct_rawffi(w_ffitype, w_obj)
+            else:
+                w_obj = space.interp_w(W__StructInstance, w_obj)
+                self.handle_struct(w_ffitype, w_obj)
         else:
             self.error(w_ffitype, w_obj)
 
@@ -168,6 +172,14 @@
         """
         self.error(w_ffitype, w_structinstance)
 
+    def handle_struct_rawffi(self, w_ffitype, w_structinstance):
+        """
+        This method should be killed as soon as we remove support for _rawffi 
structures
+        
+        w_structinstance: W_StructureInstance
+        """
+        self.error(w_ffitype, w_structinstance)
+
 
 
 class ToAppLevelConverter(object):
@@ -222,8 +234,12 @@
             return self._singlefloat(w_ffitype)
         elif w_ffitype.is_struct():
             w_structdescr = w_ffitype.w_structdescr
-            assert isinstance(w_structdescr, W__StructDescr)
-            return self.get_struct(w_ffitype, w_structdescr)
+            if isinstance(w_structdescr, W__StructDescr):
+                return self.get_struct(w_ffitype, w_structdescr)
+            elif isinstance(w_structdescr, W_Structure):
+                return self.get_struct_rawffi(w_ffitype, w_structdescr)
+            else:
+                raise OperationError(self.space.w_TypeError, "Unsupported 
struct shape")
         elif w_ffitype.is_void():
             voidval = self.get_void(w_ffitype)
             assert voidval is None
@@ -325,6 +341,15 @@
 
     def get_struct(self, w_ffitype, w_structdescr):
         """
+        Return type: lltype.Signed
+        (the address of the structure)
+        """
+        self.error(w_ffitype)
+
+    def get_struct_rawffi(self, w_ffitype, w_structdescr):
+        """
+        This should be killed as soon as we kill support for _rawffi structures
+        
         Return type: lltype.Unsigned
         (the address of the structure)
         """
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to