[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