[pypy-svn] r54531 - in pypy/dist/pypy/rlib: . test
arigo at codespeak.net
arigo at codespeak.net
Wed May 7 15:21:57 CEST 2008
Author: arigo
Date: Wed May 7 15:21:56 2008
New Revision: 54531
Modified:
pypy/dist/pypy/rlib/rarithmetic.py
pypy/dist/pypy/rlib/rbigint.py
pypy/dist/pypy/rlib/test/test_rbigint.py
Log:
Fix rbigint to accept any r_xxx number type when
building a bigint. Add test for this.
Modified: pypy/dist/pypy/rlib/rarithmetic.py
==============================================================================
--- pypy/dist/pypy/rlib/rarithmetic.py (original)
+++ pypy/dist/pypy/rlib/rarithmetic.py Wed May 7 15:21:56 2008
@@ -21,6 +21,11 @@
like r_int but double word size
r_ulonglong
like r_uint but double word size
+widen(x)
+ if x is of a type smaller than lltype.Signed or
+ lltype.Unsigned, widen it to lltype.Signed.
+ Useful because the translator doesn't support
+ arithmetic on the smaller types.
These are meant to be erased by translation, r_uint
in the process should mark unsigned values, ovfcheck should
@@ -68,6 +73,25 @@
n -= 2*LONG_TEST
return int(n)
+def widen(n):
+ from pypy.rpython.lltypesystem import lltype
+ if _should_widen_type(lltype.typeOf(n)):
+ return int(n)
+ else:
+ return n
+widen._annspecialcase_ = 'specialize:argtype(0)'
+
+def _should_widen_type(tp):
+ from pypy.rpython.lltypesystem import lltype, rffi
+ if tp is lltype.Bool:
+ return True
+ if tp is lltype.Signed:
+ return False
+ r_class = rffi.platform.numbertype_to_rclass[tp]
+ assert issubclass(r_class, base_int)
+ return r_class.BITS < LONG_BIT
+_should_widen_type._annspecialcase_ = 'specialize:memo'
+
del _bits, _itest, _Ltest
def ovfcheck(r):
Modified: pypy/dist/pypy/rlib/rbigint.py
==============================================================================
--- pypy/dist/pypy/rlib/rbigint.py (original)
+++ pypy/dist/pypy/rlib/rbigint.py Wed May 7 15:21:56 2008
@@ -1,5 +1,5 @@
from pypy.rlib.rarithmetic import LONG_BIT, intmask, r_uint, r_ulonglong
-from pypy.rlib.rarithmetic import ovfcheck, r_longlong
+from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen
import math, sys
@@ -613,7 +613,7 @@
return digits
digits_for_most_neg_long._annspecialcase_ = "specialize:argtype(0)"
-def args_from_rarith_int(x):
+def args_from_rarith_int1(x):
if x > 0:
return digits_from_nonneg_long(x), 1
elif x == 0:
@@ -631,6 +631,10 @@
else:
# the most negative integer! hacks needed...
return digits_for_most_neg_long(x), -1
+args_from_rarith_int1._annspecialcase_ = "specialize:argtype(0)"
+
+def args_from_rarith_int(x):
+ return args_from_rarith_int1(widen(x))
args_from_rarith_int._annspecialcase_ = "specialize:argtype(0)"
# ^^^ specialized by the precise type of 'x', which is typically a r_xxx
# instance from rlib.rarithmetic
Modified: pypy/dist/pypy/rlib/test/test_rbigint.py
==============================================================================
--- pypy/dist/pypy/rlib/test/test_rbigint.py (original)
+++ pypy/dist/pypy/rlib/test/test_rbigint.py Wed May 7 15:21:56 2008
@@ -434,15 +434,25 @@
def test_args_from_rarith_int(self):
from pypy.rpython.test.test_llinterp import interpret
- def fn(x):
- n1 = rbigint.fromrarith_int(x)
- n2 = rbigint.fromrarith_int(r_uint(x))
- return '%s %s' % (n1.str(), n2.str())
- res = interpret(fn, [0])
- assert ''.join(res.chars) == '0 0'
- res = interpret(fn, [sys.maxint])
- assert ''.join(res.chars) == '%d %d' % (sys.maxint, sys.maxint)
- res = interpret(fn, [-sys.maxint-1])
- assert ''.join(res.chars) == '%d %d' % (-sys.maxint-1, sys.maxint+1)
- res = interpret(fn, [-17])
- assert ''.join(res.chars) == '%d %d' % (-17, 2*sys.maxint+2-17)
+ from pypy.rpython.tool.rfficache import platform
+ classlist = platform.numbertype_to_rclass.values()
+ fnlist = []
+ for r in classlist:
+ if r is int:
+ mask = sys.maxint*2+1
+ signed = True
+ else:
+ mask = r.MASK
+ signed = r.SIGNED
+ values = [0, -1, mask>>1, -(mask>>1)-1]
+ if not signed:
+ values = [x & mask for x in values]
+ values = [r(x) for x in values]
+
+ def fn(i):
+ n = rbigint.fromrarith_int(values[i])
+ return n.str()
+
+ for i in range(len(values)):
+ res = interpret(fn, [i])
+ assert ''.join(res.chars) == str(long(values[i]))
More information about the Pypy-commit
mailing list