[pypy-commit] pypy ffistruct: add support for longlongs at applevel

antocuni noreply at buildbot.pypy.org
Wed Nov 9 13:51:20 CET 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: ffistruct
Changeset: r49008:4e792ca0116c
Date: 2011-11-09 13:49 +0100
http://bitbucket.org/pypy/pypy/changeset/4e792ca0116c/

Log:	add support for longlongs at applevel

diff --git a/pypy/module/_ffi/interp_struct.py b/pypy/module/_ffi/interp_struct.py
--- a/pypy/module/_ffi/interp_struct.py
+++ b/pypy/module/_ffi/interp_struct.py
@@ -2,7 +2,7 @@
 from pypy.rlib import clibffi
 from pypy.rlib import libffi
 from pypy.rlib import jit
-from pypy.rlib.rarithmetic import r_uint
+from pypy.rlib.rarithmetic import r_uint, r_ulonglong
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
 from pypy.interpreter.gateway import interp2app, unwrap_spec
@@ -130,19 +130,34 @@
     @unwrap_spec(name=str)
     def getfield(self, space, name):
         w_ffitype, offset = self.structdescr.get_type_and_offset_for_field(name)
-        value = libffi.struct_getfield_int(w_ffitype.ffitype, self.rawmem, offset)
-        if w_ffitype.is_unsigned():
-            return space.wrap(r_uint(value))
-        return space.wrap(value)
+        if w_ffitype.is_longlong():
+            value = libffi.struct_getfield_longlong(w_ffitype.ffitype, self.rawmem, offset)
+            if w_ffitype is app_types.ulonglong:
+                return space.wrap(r_ulonglong(value))
+            return space.wrap(value)
+        #
+        if w_ffitype.is_signed() or w_ffitype.is_unsigned():
+            value = libffi.struct_getfield_int(w_ffitype.ffitype, self.rawmem, offset)
+            if w_ffitype.is_unsigned():
+                return space.wrap(r_uint(value))
+            return space.wrap(value)
+        #
+        assert False, 'unknown type'
 
     @unwrap_spec(name=str)
     def setfield(self, space, name, w_value):
         w_ffitype, offset = self.structdescr.get_type_and_offset_for_field(name)
-        # XXX: add support for long long
+        if w_ffitype.is_longlong():
+            value = space.truncatedlonglong_w(w_value)
+            libffi.struct_setfield_longlong(w_ffitype.ffitype, self.rawmem, offset, value)
+            return
+        #
         if w_ffitype.is_signed() or w_ffitype.is_unsigned():
             value = space.truncatedint(w_value)
+            libffi.struct_setfield_int(w_ffitype.ffitype, self.rawmem, offset, value)
+            return
         #
-        libffi.struct_setfield_int(w_ffitype.ffitype, self.rawmem, offset, value)
+        assert False, 'unknown type'
 
 W__StructInstance.typedef = TypeDef(
     '_StructInstance',
diff --git a/pypy/module/_ffi/test/test_struct.py b/pypy/module/_ffi/test/test_struct.py
--- a/pypy/module/_ffi/test/test_struct.py
+++ b/pypy/module/_ffi/test/test_struct.py
@@ -177,6 +177,23 @@
         struct.setfield('ulong', sys.maxint*2 + 2)
         assert struct.getfield('ulong') == 0
 
+    def test_getfield_setfield_longlong(self):
+        import sys
+        from _ffi import _StructDescr, Field, types
+        longsize = types.slong.sizeof()
+        fields = [
+            Field('slonglong', types.slonglong),
+            Field('ulonglong', types.ulonglong),
+            ]
+        descr = _StructDescr('foo', fields)
+        struct = descr.allocate()
+        struct.setfield('slonglong', 9223372036854775808)
+        assert struct.getfield('slonglong') == -9223372036854775808
+        struct.setfield('ulonglong', -1)
+        assert struct.getfield('ulonglong') == 18446744073709551615        
+        mem = self.read_raw_mem(struct.getaddr(), 'c_longlong', 2)
+        assert mem == [-9223372036854775808, -1]
+
     def test_compute_shape(self):
         from _ffi import Structure, Field, types
         class Point(Structure):


More information about the pypy-commit mailing list