[pypy-svn] r41025 - in pypy/dist/pypy/rpython: . test

mwh at codespeak.net mwh at codespeak.net
Thu Mar 22 12:51:40 CET 2007


Author: mwh
Date: Thu Mar 22 12:51:38 2007
New Revision: 41025

Modified:
   pypy/dist/pypy/rpython/llinterp.py
   pypy/dist/pypy/rpython/rint.py
   pypy/dist/pypy/rpython/test/test_rint.py
Log:
issue 300 testing

the root problem was that the '_zer' variants of the division and modulo
operations weren't getting their results adjusted, so be cleaner and more
comprehensive there.  the fix was held up for a while finding out that the
llinterp's implementation of op_int_floordiv_ovf and so on didn't get updated
when they should have (in rev 40556), but that's fixed now.  add (hopefully)
comprehensive tests.


Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py	(original)
+++ pypy/dist/pypy/rpython/llinterp.py	Thu Mar 22 12:51:38 2007
@@ -841,12 +841,26 @@
             checkfn = 'intmask'
         else:
             checkfn = ''
+        if operator == '//':
+            code = '''r = %(checkfn)s(x // y)
+                if x^y < 0 and x%%y != 0:
+                    r += 1
+                return r
+                '''%locals()
+        elif operator == '%':
+            code = '''r = %(checkfn)s(x %% y)
+                if x^y < 0 and x%%y != 0:
+                    r -= y
+                return r
+                '''%locals()
+        else:
+            code = 'return %(checkfn)s(x %(operator)s y)'%locals()
         exec py.code.Source("""
         def %(fn)s(self, x, y):
             assert isinstance(x, %(xtype)s)
             assert isinstance(y, %(ytype)s)
             try:
-                return %(checkfn)s(x %(operator)s y)
+                %(code)s
             except (OverflowError, ValueError, ZeroDivisionError):
                 self.make_llexception()
         """ % locals()).compile() in globals(), d

Modified: pypy/dist/pypy/rpython/rint.py
==============================================================================
--- pypy/dist/pypy/rpython/rint.py	(original)
+++ pypy/dist/pypy/rpython/rint.py	Thu Mar 22 12:51:38 2007
@@ -208,7 +208,9 @@
         assert isinstance(repr.lowleveltype, Number)
         c_zero = inputconst(repr.lowleveltype, repr.lowleveltype._default)
 
-        if func in ('floordiv', 'floordiv_ovf'):
+        op = func.split('_', 1)[0]
+
+        if op == 'floordiv':
             # return (x/y) - (((x^y)<0)&((x%y)!=0));
             v_xor = hop.genop(prefix + 'xor', vlist,
                             resulttype=repr)
@@ -224,7 +226,7 @@
                              resulttype=repr)
             v_res = hop.genop(prefix + 'sub', [v_res, v_corr],
                               resulttype=repr)
-        elif func in ('mod', 'mod_ovf'):
+        elif op == 'mod':
             # return r + y*(((x^y)<0)&(r!=0));
             v_xor = hop.genop(prefix + 'xor', vlist,
                             resulttype=repr)

Modified: pypy/dist/pypy/rpython/test/test_rint.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rint.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rint.py	Thu Mar 22 12:51:38 2007
@@ -245,6 +245,68 @@
                 res = self.interpret(m, [x, y])
                 assert res == m(x, y)
 
+    def test_protected_div_mod(self):
+        def div_unpro(x, y):
+            return x//y
+        def div_ovf(x, y):
+            try:
+                return ovfcheck(x//y)
+            except OverflowError:
+                return 42
+        def div_zer(x, y):
+            try:
+                return x//y
+            except ZeroDivisionError:
+                return 84
+        def div_ovf_zer(x, y):
+            try:
+                return ovfcheck(x//y)
+            except OverflowError:
+                return 42
+            except ZeroDivisionError:
+                return 84
+
+        def mod_unpro(x, y):
+            return x%y
+        def mod_ovf(x, y):
+            try:
+                return ovfcheck(x%y)
+            except OverflowError:
+                return 42
+        def mod_zer(x, y):
+            try:
+                return x%y
+            except ZeroDivisionError:
+                return 84
+        def mod_ovf_zer(x, y):
+            try:
+                return ovfcheck(x%y)
+            except OverflowError:
+                return 42
+            except ZeroDivisionError:
+                return 84
+
+        for inttype in (int, r_longlong):
+
+            args = [( 5, 2), (-5, 2), ( 5,-2), (-5,-2),
+                    ( 6, 2), (-6, 2), ( 6,-2), (-6,-2),
+                    (-sys.maxint, -1), (4, 0)]
+
+            funcs = [div_unpro, div_ovf, div_zer, div_ovf_zer,
+                     mod_unpro, mod_ovf, mod_zer, mod_ovf_zer]
+
+            for func in funcs:
+                print func
+                if 'ovf' in func.func_name and inttype is r_longlong:
+                    continue # don't have many llong_*_ovf operations...
+                for x, y in args:
+                    x, y = inttype(x), inttype(y)
+                    try:
+                        res1 = ovfcheck(func(x, y))
+                    except (OverflowError, ZeroDivisionError):
+                        continue
+                    res2 = self.interpret(func, [x, y])
+                    assert res1 == res2
 
 class TestLLtype(BaseTestRint, LLRtypeMixin):
     pass



More information about the Pypy-commit mailing list