[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