[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