[pypy-svn] r72441 - in pypy/branch/rawffi-64/pypy/rlib: . test

arigo at codespeak.net arigo at codespeak.net
Sat Mar 20 13:25:29 CET 2010


Author: arigo
Date: Sat Mar 20 13:25:28 2010
New Revision: 72441

Modified:
   pypy/branch/rawffi-64/pypy/rlib/libffi.py
   pypy/branch/rawffi-64/pypy/rlib/test/test_libffi.py
Log:
The libffi.py side of things.


Modified: pypy/branch/rawffi-64/pypy/rlib/libffi.py
==============================================================================
--- pypy/branch/rawffi-64/pypy/rlib/libffi.py	(original)
+++ pypy/branch/rawffi-64/pypy/rlib/libffi.py	Sat Mar 20 13:25:28 2010
@@ -366,13 +366,26 @@
                                                    CALLBACK_TP, rffi.VOIDP],
                               rffi.INT)            
 
-def make_struct_ffitype(size, aligment):
-    tp = lltype.malloc(FFI_TYPE_P.TO, flavor='raw')
-    tp.c_type = FFI_TYPE_STRUCT
-    tp.c_size = rffi.cast(rffi.SIZE_T, size)
-    tp.c_alignment = rffi.cast(rffi.USHORT, aligment)
-    tp.c_elements = lltype.nullptr(FFI_TYPE_PP.TO)
-    return tp
+FFI_STRUCT_P = lltype.Ptr(lltype.Struct('FFI_STRUCT',
+                                        ('ffistruct', FFI_TYPE_P.TO),
+                                        ('members', lltype.Array(FFI_TYPE_P))))
+
+def make_struct_ffitype_e(size, aligment, field_types):
+    """Compute the type of a structure.  Returns a FFI_STRUCT_P out of
+       which the 'ffistruct' member is a regular FFI_TYPE.
+    """
+    tpe = lltype.malloc(FFI_STRUCT_P.TO, len(field_types)+1, flavor='raw')
+    tpe.ffistruct.c_type = FFI_TYPE_STRUCT
+    tpe.ffistruct.c_size = rffi.cast(rffi.SIZE_T, size)
+    tpe.ffistruct.c_alignment = rffi.cast(rffi.USHORT, aligment)
+    tpe.ffistruct.c_elements = rffi.cast(FFI_TYPE_PP,
+                                         lltype.direct_arrayitems(tpe.members))
+    n = 0
+    while n < len(field_types):
+        tpe.members[n] = field_types[n]
+        n += 1
+    tpe.members[n] = lltype.nullptr(FFI_TYPE_P.TO)
+    return tpe
 
 def cast_type_to_ffitype(tp):
     """ This function returns ffi representation of rpython type tp

Modified: pypy/branch/rawffi-64/pypy/rlib/test/test_libffi.py
==============================================================================
--- pypy/branch/rawffi-64/pypy/rlib/test/test_libffi.py	(original)
+++ pypy/branch/rawffi-64/pypy/rlib/test/test_libffi.py	Sat Mar 20 13:25:28 2010
@@ -233,19 +233,27 @@
         del libm
         assert not ALLOCATED
 
-    def test_make_struct_fftiype(self):
-        tp = make_struct_ffitype(6, 2)
-        assert tp.c_type == FFI_TYPE_STRUCT
-        assert tp.c_size == 6
-        assert tp.c_alignment == 2
-        lltype.free(tp, flavor='raw')
+    def test_make_struct_ffitype_e(self):
+        tpe = make_struct_ffitype_e(16, 4, [ffi_type_pointer, ffi_type_uchar])
+        assert tpe.ffistruct.c_type == FFI_TYPE_STRUCT
+        assert tpe.ffistruct.c_size == 16
+        assert tpe.ffistruct.c_alignment == 4
+        assert tpe.ffistruct.c_elements[0] == ffi_type_pointer
+        assert tpe.ffistruct.c_elements[1] == ffi_type_uchar
+        assert not tpe.ffistruct.c_elements[2]
+        lltype.free(tpe, flavor='raw')
+
+    def test_nested_struct_elements(self):
+        tpe2 = make_struct_ffitype_e(16, 4, [ffi_type_pointer, ffi_type_uchar])
+        tp2 = tpe2.ffistruct
+        tpe = make_struct_ffitype_e(32, 4, [tp2, ffi_type_schar])
+        assert tpe.ffistruct.c_elements[0] == tp2
+        assert tpe.ffistruct.c_elements[1] == ffi_type_schar
+        assert not tpe.ffistruct.c_elements[2]
+        lltype.free(tpe, flavor='raw')
+        lltype.free(tpe2, flavor='raw')
 
     def test_struct_by_val(self):
-        import platform
-        if platform.machine() == 'x86_64':
-            py.test.skip("Segfaults on x86_64 because small structures "
-                         "may be passed in registers and "
-                         "c_elements must not be null")
         from pypy.translator.tool.cbuild import ExternalCompilationInfo
         from pypy.translator.platform import platform
         from pypy.tool.udir import udir
@@ -277,9 +285,9 @@
         slong = cast_type_to_ffitype(rffi.LONG)
         size = slong.c_size*2
         alignment = slong.c_alignment
-        tp = make_struct_ffitype(size, alignment)
+        tpe = make_struct_ffitype_e(size, alignment, [slong, slong])
 
-        sum_x_y = lib.getrawpointer('sum_x_y', [tp], slong)
+        sum_x_y = lib.getrawpointer('sum_x_y', [tpe.ffistruct], slong)
 
         buffer = lltype.malloc(rffi.LONGP.TO, 3, flavor='raw')
         buffer[0] = 200
@@ -291,17 +299,12 @@
 
         lltype.free(buffer, flavor='raw')
         del sum_x_y
-        lltype.free(tp, flavor='raw')
+        lltype.free(tpe, flavor='raw')
         del lib
 
         assert not ALLOCATED
 
     def test_ret_struct_val(self):
-        import platform
-        if platform.machine() == 'x86_64':
-            py.test.skip("Segfaults on x86_64 because small structures "
-                         "may be passed in registers and "
-                         "c_elements must not be null")
         from pypy.translator.tool.cbuild import ExternalCompilationInfo
         from pypy.translator.platform import platform
         from pypy.tool.udir import udir
@@ -337,10 +340,10 @@
 
         size = ffi_type_sshort.c_size*2
         alignment = ffi_type_sshort.c_alignment
-        tp = make_struct_ffitype(size, alignment)
+        tpe = make_struct_ffitype_e(size, alignment, [ffi_type_sshort]*2)
 
         give  = lib.getrawpointer('give', [ffi_type_sshort, ffi_type_sshort],
-                                  tp)
+                                  tpe.ffistruct)
         inbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw')
         inbuffer[0] = rffi.cast(rffi.SHORT, 40)
         inbuffer[1] = rffi.cast(rffi.SHORT, 72)
@@ -354,7 +357,7 @@
         assert outbuffer[0] == 40
         assert outbuffer[1] == 72
 
-        perturb  = lib.getrawpointer('perturb', [tp], tp)
+        perturb  = lib.getrawpointer('perturb', [tpe.ffistruct], tpe.ffistruct)
 
         inbuffer[0] = rffi.cast(rffi.SHORT, 7)
         inbuffer[1] = rffi.cast(rffi.SHORT, 11)
@@ -372,7 +375,7 @@
         lltype.free(inbuffer, flavor='raw')
         del give
         del perturb
-        lltype.free(tp, flavor='raw')
+        lltype.free(tpe, flavor='raw')
         del lib
 
         assert not ALLOCATED



More information about the Pypy-commit mailing list