[pypy-svn] r41153 - in pypy/dist/pypy: rpython/raisingops translator/backendopt translator/backendopt/test

mwh at codespeak.net mwh at codespeak.net
Fri Mar 23 11:42:05 CET 2007


Author: mwh
Date: Fri Mar 23 11:42:04 2007
New Revision: 41153

Added:
   pypy/dist/pypy/translator/backendopt/test/test_raisingop2direct_call.py   (contents, props changed)
Modified:
   pypy/dist/pypy/rpython/raisingops/raisingops.py
   pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py
Log:
issue300 testing

still more div/mod fallout: the way raisingop2direct_call worked meant that
after it, the result of a division or modulo could end up getting adjusted
twice.  fix that, and add some tests that test raisingop2direct_call
specifically.


Modified: pypy/dist/pypy/rpython/raisingops/raisingops.py
==============================================================================
--- pypy/dist/pypy/rpython/raisingops/raisingops.py	(original)
+++ pypy/dist/pypy/rpython/raisingops/raisingops.py	Fri Mar 23 11:42:04 2007
@@ -1,5 +1,7 @@
 import sys
 from pypy.rlib.rarithmetic import r_longlong, r_uint, intmask
+from pypy.rpython.lltypesystem.lloperation import llop
+from pypy.rpython.lltypesystem.lltype import Signed
 
 #XXX original SIGNED_RIGHT_SHIFT_ZERO_FILLS not taken into account
 #XXX assuming HAVE_LONG_LONG (int_mul_ovf)
@@ -17,7 +19,7 @@
         else FAIL_ZER(err, "integer division")
     '''
     if y:
-        return int_floordiv(x, y)
+        return llop.int_floordiv(Signed, x, y)
     else:
         raise ZeroDivisionError("integer division")
 
@@ -132,7 +134,7 @@
     if y == -1 and x < 0 and (r_uint(x) << 1) == 0:
         raise OverflowError("integer division")
     else:
-        return int_floordiv(x, y)
+        return llop.int_floordiv(Signed, x, y)
 
 def int_floordiv_ovf_zer(x, y):
     '''#define OP_INT_FLOORDIV_OVF_ZER(x,y,r,err) \
@@ -153,7 +155,7 @@
     if y == -1 and x < 0 and (r_uint(x) << 1) == 0:
         raise OverflowError("integer modulo")
     else:
-        return int_mod(x, y)
+        return llop.int_mod(Signed, x, y)
 
 def int_mod_zer(x, y):
     '''#define OP_INT_MOD_ZER(x,y,r,err) \
@@ -161,7 +163,7 @@
         else FAIL_ZER(err, "integer modulo")
     '''
     if y:
-        return int_mod(x, y)
+        return llop.int_mod(Signed, x, y)
     else:
         raise ZeroDivisionError("integer modulo")
 
@@ -187,42 +189,6 @@
 
 # Helpers...
 
-def int_floordiv(x, y):
-    return x / y
-
-#def int_floordiv(x, y):
-#    xdivy = r_longlong(x / y)
-#    xmody = r_longlong(x - xdivy * y)
-#  
-#    # If the signs of x and y differ, and the remainder is non-0,
-#    # C89 doesn't define whether xdivy is now the floor or the
-#    # ceiling of the infinitely precise quotient.  We want the floor,
-#    # and we have it iff the remainder's sign matches y's.
-#    if xmody and ((y ^ xmody) < 0):
-#        xmody += y
-#        xdivy -= 1
-#        assert xmody and ((y ^ xmody) >= 0)
-#
-#    return xdivy
-
-def int_mod(x, y):
-    return x % y
-
-#def int_mod(x, y):
-#    xdivy = r_longlong(x / y)
-#    xmody = r_longlong(x - xdivy * y)
-#  
-#    # If the signs of x and y differ, and the remainder is non-0,
-#    # C89 doesn't define whether xdivy is now the floor or the
-#    # ceiling of the infinitely precise quotient.  We want the floor,
-#    # and we have it iff the remainder's sign matches y's.
-#    if xmody and ((y ^ xmody) < 0):
-#        xmody += y
-#        xdivy -= 1
-#        assert xmody and ((y ^ xmody) >= 0)
-#
-#    return xmody
-
 def _Py_ARITHMETIC_RIGHT_SHIFT(i, j):
     '''
 // Py_ARITHMETIC_RIGHT_SHIFT

Modified: pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py	(original)
+++ pypy/dist/pypy/translator/backendopt/raisingop2direct_call.py	Fri Mar 23 11:42:04 2007
@@ -2,6 +2,15 @@
 import pypy.rpython.raisingops.raisingops
 log = log.raisingop2directcall
 
+def is_raisingop(op):
+    s = op.opname
+    if (not s.startswith('int_') and not s.startswith('uint_') and
+        not s.startswith('float_') and not s.startswith('llong_')):
+       return False
+    if not s.endswith('_zer') and not s.endswith('_ovf') and not s.endswith('_val'): #not s in special_operations:
+       return False
+    return True
+
 def raisingop2direct_call(translator, graphs=None):
     """search for operations that could raise an exception and change that
     operation into a direct_call to a function from the raisingops directory.
@@ -14,14 +23,6 @@
     if graphs is None:
         graphs = translator.graphs
 
-    def is_raisingop(op):
-        s = op.opname
-        if (not s.startswith('int_') and not s.startswith('uint_') and
-            not s.startswith('float_') and not s.startswith('llong_')):
-           return False
-        if not s.endswith('_zer') and not s.endswith('_ovf') and not s.endswith('_val'): #not s in special_operations:
-           return False
-        return True
 
     log('starting')
     seen = {}

Added: pypy/dist/pypy/translator/backendopt/test/test_raisingop2direct_call.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/test/test_raisingop2direct_call.py	Fri Mar 23 11:42:04 2007
@@ -0,0 +1,119 @@
+from pypy.translator.backendopt import raisingop2direct_call, support
+from pypy.rpython.test.test_llinterp import get_interpreter
+from pypy.rlib.rarithmetic import ovfcheck
+
+import sys
+
+import py
+
+
+def get_runner(f, exceptedop, types):
+    values = [t() for t in types]
+    interp, graph = get_interpreter(f, values)
+    for op in support.graph_operations(graph):
+        if op.opname == exceptedop:
+            break
+    else:
+        assert False, "op %r not found!"%(exceptedop,)
+    t = interp.typer.annotator.translator # FIIISH!
+    raisingop2direct_call.raisingop2direct_call(t, [graph])
+    def ret(*args):
+        assert map(type, args) == types
+        return interp.eval_graph(graph, args)
+    return ret
+
+def test_test_machinery():
+    def f(x, y):
+        try:
+            return x + y
+        except OverflowError:
+            return 123
+    py.test.raises(AssertionError, "get_runner(f, 'int_add_ovf', [int, int])")
+    def f(x, y):
+        try:
+            return ovfcheck(x + y)
+        except OverflowError:
+            return 123
+    fn = get_runner(f, 'int_add_ovf', [int, int])
+    res = fn(0, 0)
+    assert res == 0
+
+
+def test_division():
+    def f(x, y):
+        try:
+            return x//y
+        except ZeroDivisionError:
+            return 123
+    fn = get_runner(f, 'int_floordiv_zer', [int, int])
+    res = fn(1, 0)
+    assert res == 123
+    res = fn(-5, 2)
+    assert res == -3
+
+    # this becomes an int_floordiv_ovf_zer already?
+##     def g(x, y):
+##         try:
+##             return ovfcheck(x//y)
+##         except OverflowError:
+##             return 123
+##     gn = get_runner(g, 'int_floordiv_ovf', [int, int])
+##     res = gn(-sys.maxint-1, -1)
+##     assert res == 123
+##     res = gn(-5, 2)
+##     assert res == -3
+
+    def h(x, y):
+        try:
+            return ovfcheck(x//y)
+        except OverflowError:
+            return 123
+        except ZeroDivisionError:
+            return 246
+    hn = get_runner(h, 'int_floordiv_ovf_zer', [int, int])
+    res = hn(-sys.maxint-1, -1)
+    assert res == 123
+    res = hn(1, 0)
+    assert res == 246
+    res = hn(-5, 2)
+    assert res == -3
+
+def test_modulo():
+    def f(x, y):
+        try:
+            return x%y
+        except ZeroDivisionError:
+            return 123
+    fn = get_runner(f, 'int_mod_zer', [int, int])
+    res = fn(0, 0)
+    assert res == 123
+    res = fn(-5, 2)
+    assert res == 1
+
+
+    # this becomes an int_mod_ovf_zer already?
+##     def g(x, y):
+##         try:
+##             return ovfcheck(x%y)
+##         except OverflowError:
+##             return 123
+##     gn = get_runner(g, 'int_mod_ovf', [int, int])
+##     res = gn(-sys.maxint-1, -1)
+##     assert res == 123
+##     res = gn(-5, 2)
+##     assert res == -3
+
+    def h(x, y):
+        try:
+            return ovfcheck(x%y)
+        except OverflowError:
+            return 123
+        except ZeroDivisionError:
+            return 246
+    hn = get_runner(h, 'int_mod_ovf_zer', [int, int])
+    res = hn(-sys.maxint-1, -1)
+    assert res == 123
+    res = hn(1, 0)
+    assert res == 246
+    res = hn(-5, 2)
+    assert res == 1



More information about the Pypy-commit mailing list