[pypy-svn] pypy jitypes2: add support for long longs at applevel

antocuni commits-noreply at bitbucket.org
Wed Dec 22 16:21:40 CET 2010


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: jitypes2
Changeset: r40186:5448381b294e
Date: 2010-12-22 16:21 +0100
http://bitbucket.org/pypy/pypy/changeset/5448381b294e/

Log:	add support for long longs at applevel

diff --git a/pypy/module/_ffi/test/test__ffi.py b/pypy/module/_ffi/test/test__ffi.py
--- a/pypy/module/_ffi/test/test__ffi.py
+++ b/pypy/module/_ffi/test/test__ffi.py
@@ -186,6 +186,49 @@
         assert res == self.f_12_34_plus_56_78
 
 
+    def test_slonglong_args(self):
+        """
+            long long sum_xy_longlong(long long x, long long y)
+            {
+                return x+y;
+            }
+        """
+        from _ffi import CDLL, types
+        maxint32 = 2147483647 # we cannot really go above maxint on 64 bits
+                              # (and we would not test anything, as there long
+                              # is the same as long long)
+
+        libfoo = CDLL(self.libfoo_name)
+        sum_xy = libfoo.getfunc('sum_xy_longlong', [types.slonglong, types.slonglong],
+                                types.slonglong)
+        x = maxint32+1
+        y = maxint32+2
+        res = sum_xy(x, y)
+        expected = maxint32*2 + 3
+        assert res == expected
+
+    def test_ulonglong_args(self):
+        """
+            unsigned long long sum_xy_ulonglong(unsigned long long x,
+                                                unsigned long long y)
+            {
+                return x+y;
+            }
+        """
+        from _ffi import CDLL, types
+        maxint64 = 9223372036854775807 # maxint64+1 does not fit into a
+                                       # longlong, but it does into a
+                                       # ulonglong
+        libfoo = CDLL(self.libfoo_name)
+        sum_xy = libfoo.getfunc('sum_xy_ulonglong', [types.ulonglong, types.ulonglong],
+                                types.ulonglong)
+        x = maxint64+1
+        y = 2
+        res = sum_xy(x, y)
+        expected = maxint64 + 3
+        assert res == expected
+
+
     def test_TypeError_numargs(self):
         from _ffi import CDLL, types
         libfoo = CDLL(self.libfoo_name)

diff --git a/pypy/module/_ffi/interp_ffi.py b/pypy/module/_ffi/interp_ffi.py
--- a/pypy/module/_ffi/interp_ffi.py
+++ b/pypy/module/_ffi/interp_ffi.py
@@ -81,10 +81,28 @@
                 argchain.arg(space.float_w(w_arg))
             elif kind == 's':
                 argchain.arg_singlefloat(space.float_w(w_arg))
+            elif kind == 'I' or kind == 'U':
+                # we are on 32 bit and using long longs. Too bad, we can't jit it
+                self.arg_longlong(space, argchain, kind, w_arg)
             else:
                 assert False, "Argument kind '%s' not supported" % kind
         return argchain
 
+    @jit.dont_look_inside
+    def arg_longlong(self, space, argchain, kind, w_arg):
+        bigarg = space.bigint_w(w_arg)
+        if kind == 'I':
+            llval = bigarg.tolonglong()
+        elif kind == 'U':
+            ullval = bigarg.toulonglong()
+            llval = rffi.cast(rffi.LONGLONG, ullval)
+        else:
+            assert False
+        # this is a hack: we store the 64 bits of the long long into the
+        # 64 bits of a float (i.e., a C double)
+        floatval = libffi.longlong2float(llval)
+        argchain.arg_longlong(floatval)
+
     @unwrap_spec('self', ObjSpace, 'args_w')
     def call(self, space, args_w):
         self = jit.hint(self, promote=True)
@@ -101,7 +119,10 @@
             # the result is a float, but widened to be inside a double
             floatres = self.func.call(argchain, rffi.FLOAT)
             return space.wrap(floatres)
+        elif reskind == 'I' or reskind == 'U':
+            return self._call_longlong(space, argchain, reskind)
         else:
+            assert reskind == 'v'
             voidres = self.func.call(argchain, lltype.Void)
             assert voidres is None
             return space.w_None
@@ -161,6 +182,20 @@
                                  space.wrap('Unsupported restype'))
         return space.wrap(intres)
 
+    @jit.dont_look_inside
+    def _call_longlong(self, space, argchain, reskind):
+        # this is a hack: we store the 64 bits of the long long into the 64
+        # bits of a float (i.e., a C double)
+        floatres = self.func.call(argchain, rffi.LONGLONG)
+        llres = libffi.float2longlong(floatres)
+        if reskind == 'I':
+            return space.wrap(llres)
+        elif reskind == 'U':
+            ullres = rffi.cast(rffi.ULONGLONG, llres)
+            return space.wrap(ullres)
+        else:
+            assert False
+
     @unwrap_spec('self', ObjSpace)
     def getaddr(self, space):
         """


More information about the Pypy-commit mailing list