Author: Antonio Cuni <[email protected]>
Branch: ffistruct
Changeset: r47179:4003bd45c5ff
Date: 2011-09-09 11:46 +0200
http://bitbucket.org/pypy/pypy/changeset/4003bd45c5ff/
Log: refactor the interface for struct_{get,set}field. Now we pass the
ffitype at runtime, and the values are handled as lltype.Signed.
struct_{get,set}field take care of doing cast of the correct LLTYPE
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -231,6 +231,9 @@
lltype.Bool : _unsigned_type_for(lltype.Bool),
}
+ffitype_map = unrolling_iterable(TYPE_MAP.iteritems())
+
+
def external(name, args, result, **kwds):
return rffi.llexternal(name, args, result, compilation_info=eci, **kwds)
diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -414,9 +414,33 @@
# ======================================================================
+def struct_getfield_int(ffitype, addr, offset):
+ """
+ Return the field of type ``ffitype`` at ``addr+offset``, widened to
+ lltype.Signed.
+ """
+ for TYPE, ffitype2 in clibffi.ffitype_map:
+ if ffitype is ffitype2:
+ value = _struct_getfield(TYPE, addr, offset)
+ return rffi.cast(lltype.Signed, value)
+ assert False, "cannot find the given ffitype"
+
+def struct_setfield_int(ffitype, addr, offset, value):
+ """
+ Set the field of type ``ffitype`` at ``addr+offset``. ``value`` is of
+ type lltype.Signed, and it's automatically converted to the right type.
+ """
+ for TYPE, ffitype2 in clibffi.ffitype_map:
+ if ffitype is ffitype2:
+ value = rffi.cast(TYPE, value)
+ _struct_setfield(TYPE, addr, offset, value)
+ return
+ assert False, "cannot find the given ffitype"
+
+
@jit.dont_look_inside
@specialize.arg(0)
-def struct_getfield(TYPE, addr, offset):
+def _struct_getfield(TYPE, addr, offset):
"""
Read the field of type TYPE at addr+offset.
addr is of type rffi.VOIDP, offset is an int.
@@ -428,9 +452,9 @@
@jit.dont_look_inside
@specialize.arg(0)
-def struct_setfield(TYPE, addr, offset, value):
+def _struct_setfield(TYPE, addr, offset, value):
"""
- Read the field of type TYPE at addr+offset.
+ Write the field of type TYPE at addr+offset.
addr is of type rffi.VOIDP, offset is an int.
"""
addr = rffi.ptradd(addr, offset)
diff --git a/pypy/rlib/test/test_libffi.py b/pypy/rlib/test/test_libffi.py
--- a/pypy/rlib/test/test_libffi.py
+++ b/pypy/rlib/test/test_libffi.py
@@ -5,7 +5,7 @@
from pypy.rlib.rarithmetic import r_singlefloat, r_longlong, r_ulonglong
from pypy.rlib.test.test_clibffi import BaseFfiTest, get_libm_name,
make_struct_ffitype_e
from pypy.rlib.libffi import CDLL, Func, get_libc_name, ArgChain, types
-from pypy.rlib.libffi import IS_32_BIT, struct_getfield, struct_setfield
+from pypy.rlib.libffi import IS_32_BIT, struct_getfield_int,
struct_setfield_int
class TestLibffiMisc(BaseFfiTest):
@@ -54,18 +54,22 @@
def test_struct_fields(self):
longsize = 4 if IS_32_BIT else 8
- POINT = lltype.Struct('POINT', ('x', rffi.LONG), ('y', rffi.LONG))
+ POINT = lltype.Struct('POINT',
+ ('x', rffi.LONG),
+ ('y', rffi.SHORT)
+ )
+ y_ofs = longsize
p = lltype.malloc(POINT, flavor='raw')
p.x = 42
- p.y = 43
+ p.y = rffi.cast(rffi.SHORT, -1)
addr = rffi.cast(rffi.VOIDP, p)
- assert struct_getfield(rffi.LONG, addr, 0) == 42
- assert struct_getfield(rffi.LONG, addr, longsize) == 43
+ assert struct_getfield_int(types.slong, addr, 0) == 42
+ assert struct_getfield_int(types.sshort, addr, y_ofs) == -1
#
- struct_setfield(rffi.LONG, addr, 0, 123)
- struct_setfield(rffi.LONG, addr, longsize, 321)
- assert p.x == 123
- assert p.y == 321
+ struct_setfield_int(types.slong, addr, 0, 43)
+ struct_setfield_int(types.sshort, addr, y_ofs, 0x1234FFFE) # 0x1234 is
masked out
+ assert p.x == 43
+ assert p.y == -2
#
lltype.free(p, flavor='raw')
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit