[pypy-svn] r72471 - in pypy/branch/rawffi-64/pypy/module/_rawffi: . test

arigo at codespeak.net arigo at codespeak.net
Sat Mar 20 20:07:03 CET 2010


Author: arigo
Date: Sat Mar 20 20:07:01 2010
New Revision: 72471

Modified:
   pypy/branch/rawffi-64/pypy/module/_rawffi/array.py
   pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py
   pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py
   pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py
   pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py
Log:
Fix the tests, and general progress.


Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/array.py
==============================================================================
--- pypy/branch/rawffi-64/pypy/module/_rawffi/array.py	(original)
+++ pypy/branch/rawffi-64/pypy/module/_rawffi/array.py	Sat Mar 20 20:07:01 2010
@@ -45,7 +45,7 @@
             return W_ArrayInstanceAutoFree(space, self, length)
         return W_ArrayInstance(space, self, length)
 
-    def get_ffi_type(self):
+    def get_basic_ffi_type(self):
         return self.basicffitype
 
     def descr_call(self, space, length, w_items=None, autofree=False):
@@ -64,7 +64,9 @@
         return space.wrap(result)
 
     def descr_repr(self, space):
-        return space.wrap("<_rawffi.Array '%s' (%d, %d)>" % self.itemcode)
+        return space.wrap("<_rawffi.Array '%s' (%d, %d)>" % (self.itemcode,
+                                                             self.size,
+                                                             self.alignment))
     descr_repr.unwrap_spec = ['self', ObjSpace]
 
     def fromaddress(self, space, address, length):
@@ -234,7 +236,7 @@
             self._free()
 
 W_ArrayInstanceAutoFree.typedef = TypeDef(
-    'ArrayInstanceWithFree',
+    'ArrayInstanceAutoFree',
     __repr__    = interp2app(W_ArrayInstance.descr_repr),
     __setitem__ = interp2app(W_ArrayInstance.descr_setitem),
     __getitem__ = interp2app(W_ArrayInstance.descr_getitem),

Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py
==============================================================================
--- pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py	(original)
+++ pypy/branch/rawffi-64/pypy/module/_rawffi/callback.py	Sat Mar 20 20:07:01 2010
@@ -65,9 +65,9 @@
         self.w_callable = w_callable
         self.argshapes = unpack_argshapes(space, w_args)
         self.resshape = unpack_resshape(space, w_result)
-        ffiargs = [shape.get_ffi_type() for shape in self.argshapes]
+        ffiargs = [shape.get_basic_ffi_type() for shape in self.argshapes]
         if self.resshape is not None:
-            ffiresult = self.resshape.get_ffi_type()
+            ffiresult = self.resshape.get_basic_ffi_type()
         else:
             ffiresult = ffi_type_void
         # necessary to keep stuff alive

Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py
==============================================================================
--- pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py	(original)
+++ pypy/branch/rawffi-64/pypy/module/_rawffi/interp_rawffi.py	Sat Mar 20 20:07:01 2010
@@ -115,7 +115,7 @@
             if isinstance(shape, W_Array) and length == 1:
                 result = shape
             else:
-                ffitype = shape.get_ffi_type()
+                ffitype = shape.get_basic_ffi_type()
                 size = shape.size * length
                 result = W_Array(ffitype, size)
             shape._array_shapes[length] = result
@@ -157,10 +157,12 @@
                 pass
             else:
                 raise
+        # Array arguments not supported directly (in C, an array argument
+        # will be just a pointer).  And the result cannot be an array (at all).
         argshapes = unpack_argshapes(space, w_argtypes)
-        ffi_argtypes = [shape.get_ffi_type() for shape in argshapes]
+        ffi_argtypes = [shape.get_basic_ffi_type() for shape in argshapes]
         if resshape is not None:
-            ffi_restype = resshape.get_ffi_type()
+            ffi_restype = resshape.get_basic_ffi_type()
         else:
             ffi_restype = ffi_type_void
 
@@ -241,7 +243,7 @@
     def allocate(self, space, length, autofree=False):
         raise NotImplementedError
 
-    def get_ffi_type(self):
+    def get_basic_ffi_type(self):
         raise NotImplementedError
 
     def descr_size_alignment(self, space, n=1):
@@ -440,8 +442,8 @@
 def descr_new_funcptr(space, w_tp, addr, w_args, w_res, flags=FUNCFLAG_CDECL):
     argshapes = unpack_argshapes(space, w_args)
     resshape = unpack_resshape(space, w_res)
-    ffi_args = [shape.get_ffi_type() for shape in argshapes]
-    ffi_res = resshape.get_ffi_type()
+    ffi_args = [shape.get_basic_ffi_type() for shape in argshapes]
+    ffi_res = resshape.get_basic_ffi_type()
     ptr = RawFuncPtr('???', ffi_args, ffi_res, rffi.cast(rffi.VOIDP, addr),
                      flags)
     return space.wrap(W_FuncPtr(space, ptr, argshapes, resshape))

Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py
==============================================================================
--- pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py	(original)
+++ pypy/branch/rawffi-64/pypy/module/_rawffi/structure.py	Sat Mar 20 20:07:01 2010
@@ -14,6 +14,7 @@
 from pypy.module._rawffi.interp_rawffi import W_DataShape, W_DataInstance
 from pypy.module._rawffi.interp_rawffi import wrap_value, unwrap_value
 from pypy.module._rawffi.interp_rawffi import unpack_shape_with_length
+from pypy.module._rawffi.interp_rawffi import size_alignment
 from pypy.rlib import libffi
 from pypy.rlib.rarithmetic import intmask, r_uint
 
@@ -103,17 +104,32 @@
     descr_fieldoffset.unwrap_spec = ['self', ObjSpace, str]
 
     # get the corresponding ffi_type
-    ffi_type = lltype.nullptr(libffi.FFI_TYPE_P.TO)
+    ffi_struct = lltype.nullptr(libffi.FFI_STRUCT_P.TO)
 
-    def get_ffi_type(self):
-        if not self.ffi_type:
-            self.ffi_type = libffi.make_struct_ffitype(self.size,
-                                                       self.alignment)
-        return self.ffi_type
+    def get_basic_ffi_type(self):
+        if not self.ffi_struct:
+            # Repeated fields are delicate.  Consider for example
+            #     struct { int a[5]; }
+            # or  struct { struct {int x;} a[5]; }
+            # Seeing no corresponding doc in libffi, let's just repeat
+            # the field 5 times...
+            fieldtypes = []
+            for name, tp in self.fields:
+                basic_ffi_type = tp.get_basic_ffi_type()
+                basic_size, _ = size_alignment(basic_ffi_type)
+                total_size = tp.size
+                count = 0
+                while count + basic_size <= total_size:
+                    fieldtypes.append(basic_ffi_type)
+                    count += basic_size
+            self.ffi_struct = libffi.make_struct_ffitype_e(self.size,
+                                                           self.alignment,
+                                                           fieldtypes)
+        return self.ffi_struct.ffistruct
     
     def __del__(self):
-        if self.ffi_type:
-            lltype.free(self.ffi_type, flavor='raw')
+        if self.ffi_struct:
+            lltype.free(self.ffi_struct, flavor='raw')
     
 
 

Modified: pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py
==============================================================================
--- pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py	(original)
+++ pypy/branch/rawffi-64/pypy/module/_rawffi/test/test__rawffi.py	Sat Mar 20 20:07:01 2010
@@ -145,10 +145,15 @@
             int bah[2];
         };
 
-        struct s2a perturbarray(struct s2a inp) {
-            inp.bah[0] *= 4;
-            inp.bah[1] *= 5;
-            return inp;
+        struct s2a get_s2a(void) {
+            struct s2a outp;
+            outp.bah[0] = 4;
+            outp.bah[1] = 5;
+            return outp;
+        }
+
+        int check_s2a(struct s2a inp) {
+            return (inp.bah[0] == 4 && inp.bah[1] == 5);
         }
 
         int AAA_first_ordinal_function()
@@ -167,7 +172,7 @@
                      allocate_array
                      static_int static_double
                      sum_x_y
-                     give perturb perturbarray
+                     give perturb get_s2a check_s2a
                      AAA_first_ordinal_function
                   """.split()
         eci = ExternalCompilationInfo(export_symbols=symbols)
@@ -188,9 +193,6 @@
             cls.w_libm_name = space.wrap('libm.so')
             if sys.platform == "darwin":
                 cls.w_libm_name = space.wrap('libm.dylib')
-        import platform
-        cls.w_isx86_64 = space.wrap(platform.machine() == 'x86_64')
-                
         cls.w_sizes_and_alignments = space.wrap(dict(
             [(k, (v.c_size, v.c_alignment)) for k,v in TYPEMAP.iteritems()]))
 
@@ -675,7 +677,7 @@
         # fragile
         S = _rawffi.Structure([('x', 'c'), ('y', 'l')])
         assert (repr(_rawffi.Array((S, 2))) ==
-                "<_rawffi.Array 'V' (%d, %d)>" % (4*lsize, lsize))
+                "<_rawffi.Array '?' (%d, %d)>" % (4*lsize, lsize))
 
         assert (repr(_rawffi.Structure([('x', 'i'), ('yz', 'i')])) ==
                 "<_rawffi.Structure 'x' 'yz' (%d, %d)>" % (2*isize, isize))
@@ -829,11 +831,6 @@
             assert 0, "Did not raise"
 
     def test_struct_byvalue(self):
-        #if self.isx86_64:
-        #    skip("Segfaults on x86_64 because small structures "
-        #         "may be passed in registers and "
-        #         "c_elements must not be null")
-
         import _rawffi, sys
         X_Y = _rawffi.Structure([('x', 'l'), ('y', 'l')])
         x_y = X_Y()
@@ -849,11 +846,6 @@
         x_y.free()
 
     def test_ret_struct(self):
-        if self.isx86_64:
-            skip("Segfaults on x86_64 because small structures "
-                 "may be passed in registers and "
-                 "c_elements must not be null")
-
         import _rawffi
         S2H = _rawffi.Structure([('x', 'h'), ('y', 'h')])
         s2h = S2H()
@@ -885,39 +877,18 @@
         s2h.free()
 
     def test_ret_struct_containing_array(self):
-        if self.isx86_64:
-            skip("Segfaults on x86_64 because small structures "
-                 "may be passed in registers and "
-                 "c_elements must not be null")
-
         import _rawffi
         AoI = _rawffi.Array('i')
         S2A = _rawffi.Structure([('bah', (AoI, 2))])
-        s2a = S2A()
         lib = _rawffi.CDLL(self.lib_name)
-        perturbarray = lib.ptr('perturbarray', [(S2A, 1)], (S2A, 1))
-        s2a.x = 100
-        a2a.y = 200
-        res = perturbarray(s2a)
-        assert isinstance(res, _rawffi.StructureInstanceAutoFree)
-        assert res.shape is S2H
-        assert res.x == 13
-        assert res.y == 17
-        a1.free()
-        a2.free()
+        get_s2a = lib.ptr('get_s2a', [], (S2A, 1))
+        check_s2a = lib.ptr('check_s2a', [(S2A, 1)], 'i')
 
-        s2h.x = 7
-        s2h.y = 11
-        perturb = lib.ptr('perturb', [(S2H, 1)], (S2H, 1))
-        res = perturb(s2h)
+        res = get_s2a()
         assert isinstance(res, _rawffi.StructureInstanceAutoFree)
-        assert res.shape is S2H
-        assert res.x == 14
-        assert res.y == 33
-        assert s2h.x == 7
-        assert s2h.y == 11
-        
-        s2h.free()
+        assert res.shape is S2A
+        ok = check_s2a(res)
+        assert ok[0] == 1
 
     def test_buffer(self):
         import _rawffi



More information about the Pypy-commit mailing list