[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