[pypy-commit] pypy default: C types 'float' and 'long double'

arigo noreply at buildbot.pypy.org
Thu Oct 24 10:03:47 CEST 2013


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r67551:1532c2508a7c
Date: 2013-10-24 10:03 +0200
http://bitbucket.org/pypy/pypy/changeset/1532c2508a7c/

Log:	C types 'float' and 'long double'

diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py
--- a/pypy/module/_cffi_backend/ctypeprim.py
+++ b/pypy/module/_cffi_backend/ctypeprim.py
@@ -369,13 +369,17 @@
         return None
 
     def pack_list_of_items(self, cdata, w_ob):
-        if self.size == rffi.sizeof(rffi.DOUBLE): # XXX
-            float_list = self.space.listview_float(w_ob)
-            if float_list is not None:
+        float_list = self.space.listview_float(w_ob)
+        if float_list is not None:
+            if self.size == rffi.sizeof(rffi.DOUBLE):   # fastest path
                 from rpython.rlib.rarray import copy_list_to_raw_array
                 cdata = rffi.cast(rffi.DOUBLEP, cdata)
                 copy_list_to_raw_array(float_list, cdata)
                 return True
+            elif self.size == rffi.sizeof(rffi.FLOAT):
+                misc.pack_float_list_to_raw_array(float_list, cdata,
+                                                  rffi.FLOAT, rffi.FLOATP)
+                return True
         return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)
 
 
@@ -431,3 +435,11 @@
         else:
             value = space.float_w(space.float(w_ob))
             self._to_longdouble_and_write(value, cdata)
+
+    def pack_list_of_items(self, cdata, w_ob):
+        float_list = self.space.listview_float(w_ob)
+        if float_list is not None:
+            misc.pack_float_list_to_raw_array(float_list, cdata,
+                                             rffi.LONGDOUBLE, rffi.LONGDOUBLEP)
+            return True
+        return W_CTypePrimitive.pack_list_of_items(self, cdata, w_ob)
diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -329,3 +329,10 @@
                 ptr[i] = rffi.cast(TP, x)
             return 0
     raise NotImplementedError("bad integer size")
+
+ at specialize.arg(2)
+def pack_float_list_to_raw_array(float_list, target, TP, TPP):
+    target = rffi.cast(TPP, target)
+    for i in range(len(float_list)):
+        x = float_list[i]
+        target[i] = rffi.cast(TP, x)
diff --git a/pypy/module/_cffi_backend/test/test_fastpath.py b/pypy/module/_cffi_backend/test/test_fastpath.py
--- a/pypy/module/_cffi_backend/test/test_fastpath.py
+++ b/pypy/module/_cffi_backend/test/test_fastpath.py
@@ -87,6 +87,24 @@
         raises(OverflowError, _cffi_backend.newp, ULONG_ARRAY, [-1])
         raises(OverflowError, _cffi_backend.newp, ULONG_ARRAY, [-sys.maxint])
 
+    def test_fast_init_cfloat_from_list(self):
+        import _cffi_backend
+        FLOAT = _cffi_backend.new_primitive_type('float')
+        P_FLOAT = _cffi_backend.new_pointer_type(FLOAT)
+        FLOAT_ARRAY = _cffi_backend.new_array_type(P_FLOAT, None)
+        buf = _cffi_backend.newp(FLOAT_ARRAY, [1.25, -3.5])
+        assert buf[0] == 1.25
+        assert buf[1] == -3.5
+
+    def test_fast_init_clongdouble_from_list(self):
+        import _cffi_backend
+        LONGDOUBLE = _cffi_backend.new_primitive_type('long double')
+        P_LONGDOUBLE = _cffi_backend.new_pointer_type(LONGDOUBLE)
+        LONGDOUBLE_ARRAY = _cffi_backend.new_array_type(P_LONGDOUBLE, None)
+        buf = _cffi_backend.newp(LONGDOUBLE_ARRAY, [1.25, -3.5])
+        assert float(buf[0]) == 1.25
+        assert float(buf[1]) == -3.5
+
 
 class AppTest_fast_path_bug(object):
     spaceconfig = dict(usemodules=('_cffi_backend', 'cStringIO'))


More information about the pypy-commit mailing list