[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