[pypy-svn] pypy jitypes2: support for ulonglong

antocuni commits-noreply at bitbucket.org
Tue Dec 21 17:22:47 CET 2010


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: jitypes2
Changeset: r40167:1651aae99e79
Date: 2010-12-21 14:22 +0100
http://bitbucket.org/pypy/pypy/changeset/1651aae99e79/

Log:	support for ulonglong

diff --git a/pypy/rlib/libffi.py b/pypy/rlib/libffi.py
--- a/pypy/rlib/libffi.py
+++ b/pypy/rlib/libffi.py
@@ -108,8 +108,8 @@
             val = rffi.cast(rffi.LONG, val)
         elif TYPE is rffi.DOUBLE:
             cls = FloatArg
-        elif TYPE in (rffi.LONGLONG, rffi.ULONGLONG):
-            raise TypeError, 'r_(u)longlong not supported by arg(), use arg_longlong()'
+        elif TYPE is rffi.LONGLONG or TYPE is rffi.ULONGLONG:
+            raise TypeError, 'r_(u)longlong not supported by arg(), use arg_(u)longlong()'
         elif TYPE is rffi.FLOAT:
             raise TypeError, 'r_singlefloat not supported by arg(), use arg_singlefloat()'
         else:
@@ -264,9 +264,10 @@
             # XXX: even if RESULT is FLOAT, we still return a DOUBLE, else the
             # jit complains. Note that the jit is disabled in this case
             return self._do_call_single_float(self.funcsym, ll_args)
-        elif RESULT is rffi.LONGLONG:
+        elif RESULT is rffi.LONGLONG or RESULT is rffi.ULONGLONG:
             # XXX: even if RESULT is LONGLONG, we still return a DOUBLE, else the
             # jit complains. Note that the jit is disabled in this case
+            # (it's not a typo, we really return a DOUBLE)
             return self._do_call_longlong(self.funcsym, ll_args)
         elif RESULT is lltype.Void:
             return self._do_call_void(self.funcsym, ll_args)

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
@@ -2,7 +2,7 @@
 import sys
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rpython.lltypesystem.ll2ctypes import ALLOCATED
-from pypy.rlib.rarithmetic import r_singlefloat, r_longlong
+from pypy.rlib.rarithmetic import r_singlefloat, r_longlong, r_ulonglong
 from pypy.rlib.test.test_clibffi import BaseFfiTest, get_libm_name
 from pypy.rlib.libffi import CDLL, Func, get_libc_name, ArgChain, types, longlong2float, float2longlong
 
@@ -121,6 +121,9 @@
                 chain.arg_singlefloat(float(arg))
             elif isinstance(arg, r_longlong):
                 chain.arg_longlong(longlong2float(arg))
+            elif isinstance(arg, r_ulonglong):
+                arg = rffi.cast(rffi.LONGLONG, arg)
+                chain.arg_longlong(longlong2float(arg))
             else:
                 chain.arg(arg)
         return func.call(chain, RESULT)
@@ -302,7 +305,8 @@
                               # (and we would not test anything, as there long
                               # is the same as long long)
         libfoo = self.get_libfoo()
-        func = (libfoo, 'sum_xy_longlong', [types.slonglong, types.slonglong], types.slonglong)
+        func = (libfoo, 'sum_xy_longlong', [types.slonglong, types.slonglong],
+                types.slonglong)
         x = r_longlong(maxint32+1)
         y = r_longlong(maxint32+2)
         res = self.call(func, [x, y], rffi.LONGLONG, init_result=0)
@@ -313,6 +317,30 @@
         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;
+            }
+        """
+        maxint64 = 9223372036854775807 # maxint64+1 does not fit into a
+                                       # longlong, but it does into a
+                                       # ulonglong
+        libfoo = self.get_libfoo()
+        func = (libfoo, 'sum_xy_ulonglong', [types.ulonglong, types.ulonglong],
+                types.ulonglong)
+        x = r_ulonglong(maxint64+1)
+        y = r_ulonglong(2)
+        res = self.call(func, [x, y], rffi.ULONGLONG, init_result=0)
+        if types.ulonglong is not types.ulong:
+            # obscure, on 32bit it's really a long long, so it returns a
+            # DOUBLE because of the JIT hack
+            res = float2longlong(res)
+            res = rffi.cast(rffi.ULONGLONG, res)
+        expected = maxint64 + 3
+        assert res == expected
 
     def test_wrong_number_of_arguments(self):
         from pypy.rpython.llinterp import LLException


More information about the Pypy-commit mailing list