Author: Antonio Cuni <anto.c...@gmail.com>
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
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to