[pypy-commit] pypy ffistruct: applevel support for single float fields

antocuni noreply at buildbot.pypy.org
Wed Nov 9 19:12:10 CET 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: ffistruct
Changeset: r49041:119ae38c2394
Date: 2011-11-09 18:23 +0100
http://bitbucket.org/pypy/pypy/changeset/119ae38c2394/

Log:	applevel support for single float fields

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
@@ -3,7 +3,7 @@
 from pypy.rlib import libffi
 from pypy.rlib import jit
 from pypy.rlib.rgc import must_be_light_finalizer
-from pypy.rlib.rarithmetic import r_uint, r_ulonglong
+from pypy.rlib.rarithmetic import r_uint, r_ulonglong, r_singlefloat
 from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.typedef import TypeDef, interp_attrproperty
 from pypy.interpreter.gateway import interp2app, unwrap_spec
@@ -149,6 +149,10 @@
             value = libffi.struct_getfield_float(w_ffitype.ffitype, self.rawmem, offset)
             return space.wrap(value)
         #
+        if w_ffitype.is_singlefloat():
+            value = libffi.struct_getfield_singlefloat(w_ffitype.ffitype, self.rawmem, offset)
+            return space.wrap(float(value))
+        #
         assert False, 'unknown type'
 
     @unwrap_spec(name=str)
@@ -169,6 +173,11 @@
             libffi.struct_setfield_float(w_ffitype.ffitype, self.rawmem, offset, value)
             return
         #
+        if w_ffitype.is_singlefloat():
+            value = r_singlefloat(space.float_w(w_value))
+            libffi.struct_setfield_singlefloat(w_ffitype.ffitype, self.rawmem, offset, value)
+            return
+        #
         assert False, 'unknown type'
 
 W__StructInstance.typedef = TypeDef(
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
@@ -182,6 +182,25 @@
         mem = self.read_raw_mem(struct.getaddr(), 'c_double', 1)
         assert mem == [123.4]
 
+    def test_getfield_setfield_singlefloat(self):
+        import sys
+        from _ffi import _StructDescr, Field, types
+        longsize = types.slong.sizeof()
+        fields = [
+            Field('x', types.float),
+            ]
+        descr = _StructDescr('foo', fields)
+        struct = descr.allocate()
+        struct.setfield('x', 123.4) # this is a value which DOES loose
+                                    # precision in a single float
+        assert 0 < abs(struct.getfield('x') - 123.4) < 0.0001
+        #
+        struct.setfield('x', 123.5) # this is a value which does not loose
+                                    # precision in a single float
+        assert struct.getfield('x') == 123.5
+        mem = self.read_raw_mem(struct.getaddr(), 'c_float', 1)
+        assert mem == [123.5]
+
     def test_compute_shape(self):
         from _ffi import Structure, Field, types
         class Point(Structure):


More information about the pypy-commit mailing list