[pypy-svn] r52784 - in pypy/branch/jit-hotpath/pypy/rpython: . lltypesystem lltypesystem/test
arigo at codespeak.net
arigo at codespeak.net
Thu Mar 20 18:34:26 CET 2008
Author: arigo
Date: Thu Mar 20 18:34:24 2008
New Revision: 52784
Modified:
pypy/branch/jit-hotpath/pypy/rpython/llinterp.py
pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/lloperation.py
pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/opimpl.py
pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/test/test_lloperation.py
Log:
(cfbolz, arigo)
Make all the 'tryfold' operations directly runnable too,
for example all ovf-checking arithmetic.
(done by moving their implementation from llinterp.py to opimpl.py)
Modified: pypy/branch/jit-hotpath/pypy/rpython/llinterp.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rpython/llinterp.py (original)
+++ pypy/branch/jit-hotpath/pypy/rpython/llinterp.py Thu Mar 20 18:34:24 2008
@@ -1,6 +1,4 @@
from pypy.objspace.flow.model import FunctionGraph, Constant, Variable, c_last_exception
-from pypy.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong
-from pypy.rlib.rarithmetic import r_ulonglong, ovfcheck_lshift
from pypy.rpython.lltypesystem import lltype, llmemory, lloperation, llheap
from pypy.rpython.lltypesystem import rclass
from pypy.rpython.ootypesystem import ootype
@@ -243,8 +241,19 @@
ophandler = getattr(self, 'op_' + opname, None)
if ophandler is None:
# try to import the operation from opimpl.py
- ophandler = lloperation.LL_OPERATIONS[opname].fold
- setattr(self.__class__, 'op_' + opname, staticmethod(ophandler))
+ llop = lloperation.LL_OPERATIONS[opname]
+ if llop.canraise:
+ assert not getattr(llop.fold, 'need_result_type', False)
+ # ^^^ for now
+ def ophandler(self, *args):
+ try:
+ return llop.fold(*args)
+ except llop.canraise:
+ self.make_llexception()
+ else:
+ ophandler = staticmethod(llop.fold)
+ setattr(self.__class__, 'op_' + opname, ophandler)
+ ophandler = getattr(self, 'op_' + opname)
return ophandler
# _______________________________________________________
# evaling functions
@@ -513,9 +522,6 @@
import pdb
pdb.set_trace()
- def op_debug_assert(self, x, msg):
- assert x, msg
-
def op_debug_fatalerror(self, ll_msg, ll_exc=None):
msg = ''.join(ll_msg.chars)
if ll_exc is None:
@@ -901,129 +907,9 @@
def op_call_boehm_gc_alloc(self):
raise NotImplementedError("call_boehm_gc_alloc")
- # ____________________________________________________________
- # Overflow-detecting variants
-
- def op_int_neg_ovf(self, x):
- assert type(x) is int
- try:
- return ovfcheck(-x)
- except OverflowError:
- self.make_llexception()
-
- def op_int_abs_ovf(self, x):
- assert type(x) is int
- try:
- return ovfcheck(abs(x))
- except OverflowError:
- self.make_llexception()
-
- def op_llong_neg_ovf(self, x):
- assert type(x) is r_longlong
- try:
- return ovfcheck(-x)
- except OverflowError:
- self.make_llexception()
-
- def op_llong_abs_ovf(self, x):
- assert type(x) is r_longlong
- try:
- return ovfcheck(abs(x))
- except OverflowError:
- self.make_llexception()
-
- def op_int_lshift_ovf(self, x, y):
- assert isinstance(x, int)
- assert isinstance(y, int)
- try:
- return ovfcheck_lshift(x, y)
- except OverflowError:
- self.make_llexception()
-
- def op_int_lshift_ovf_val(self, x, y):
- assert isinstance(x, int)
- assert isinstance(y, int)
- try:
- return ovfcheck_lshift(x, y)
- except (OverflowError, ValueError):
- self.make_llexception()
-
- def _makefunc2(fn, operator, xtype, ytype=None):
- import sys
- d = sys._getframe(1).f_locals
- if ytype is None:
- ytype = xtype
- if '_ovf' in fn:
- checkfn = 'ovfcheck'
- elif fn.startswith('op_int_'):
- 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:
- %(code)s
- except (OverflowError, ValueError, ZeroDivisionError):
- self.make_llexception()
- """ % locals()).compile() in globals(), d
-
- _makefunc2('op_int_add_ovf', '+', '(int, llmemory.AddressOffset)')
- _makefunc2('op_int_mul_ovf', '*', '(int, llmemory.AddressOffset)', 'int')
- _makefunc2('op_int_sub_ovf', '-', 'int')
- _makefunc2('op_int_floordiv_ovf', '//', 'int')
- _makefunc2('op_int_floordiv_zer', '//', 'int')
- _makefunc2('op_int_floordiv_ovf_zer', '//', 'int')
- _makefunc2('op_int_mod_ovf', '%', 'int')
- _makefunc2('op_int_mod_zer', '%', 'int')
- _makefunc2('op_int_mod_ovf_zer', '%', 'int')
- _makefunc2('op_int_lshift_val', '<<', 'int')
- _makefunc2('op_int_rshift_val', '>>', 'int')
-
- _makefunc2('op_uint_floordiv_zer', '//', 'r_uint')
- _makefunc2('op_uint_mod_zer', '%', 'r_uint')
- _makefunc2('op_uint_lshift_val', '<<', 'r_uint')
- _makefunc2('op_uint_rshift_val', '>>', 'r_uint')
-
- _makefunc2('op_llong_floordiv_zer', '//', 'r_longlong')
- _makefunc2('op_llong_mod_zer', '%', 'r_longlong')
- _makefunc2('op_llong_lshift_val', '<<', 'r_longlong')
- _makefunc2('op_llong_rshift_val', '>>', 'r_longlong')
-
- _makefunc2('op_ullong_floordiv_zer', '//', 'r_ulonglong')
- _makefunc2('op_ullong_mod_zer', '%', 'r_ulonglong')
- _makefunc2('op_ullong_lshift_val', '<<', 'r_ulonglong')
- _makefunc2('op_ullong_rshift_val', '>>', 'r_ulonglong')
-
- def op_int_add_nonneg_ovf(self, x, y):
- if isinstance(y, int):
- assert y >= 0
- return self.op_int_add_ovf(x, y)
-
- def op_cast_float_to_int(self, f):
- assert type(f) is float
- try:
- return ovfcheck(int(f))
- except OverflowError:
- self.make_llexception()
+ # special case
def op_int_is_true(self, x):
- # special case
if type(x) is CDefinedIntSymbolic:
x = x.default
assert isinstance(x, int)
Modified: pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/lloperation.py Thu Mar 20 18:34:24 2008
@@ -44,7 +44,7 @@
self.canraise += (StackException,)
# The operation can be run directly with __call__
- self.canrun = canrun or canfold
+ self.canrun = canrun or self.tryfold
# The operation belongs to the ootypesystem
self.oo = oo
@@ -55,7 +55,7 @@
def __call__(self, RESULTTYPE, *args):
# llop is meant to be rtyped and not called directly, unless it is
- # a canfold=True operation
+ # a canfold=True or tryfold=True operation
fold = self.fold
if getattr(fold, 'need_result_type', False):
val = fold(RESULTTYPE, *args)
Modified: pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/opimpl.py (original)
+++ pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/opimpl.py Thu Mar 20 18:34:24 2008
@@ -1,7 +1,10 @@
import sys
import math
+import py
from pypy.tool.sourcetools import func_with_new_name
from pypy.rlib.objectmodel import ComputedIntSymbolic
+from pypy.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong
+from pypy.rlib.rarithmetic import r_ulonglong, ovfcheck_lshift
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.lltypesystem.lloperation import opimpls
@@ -402,6 +405,9 @@
raise TypeError("cannot fold getfield on mutable array")
return p[index]
+def op_debug_assert(x, msg):
+ assert x, msg
+
def op_debug_print(*args):
for arg in args:
print >> sys.stderr, arg,
@@ -414,6 +420,101 @@
raise DebugFatalError(*args)
# ____________________________________________________________
+# Overflow-detecting variants
+
+def op_int_neg_ovf(x):
+ assert type(x) is int
+ return ovfcheck(-x)
+
+def op_int_abs_ovf(x):
+ assert type(x) is int
+ return ovfcheck(abs(x))
+
+def op_llong_neg_ovf(x):
+ assert type(x) is r_longlong
+ return ovfcheck(-x)
+
+def op_llong_abs_ovf(x):
+ assert type(x) is r_longlong
+ return ovfcheck(abs(x))
+
+def op_int_lshift_ovf(x, y):
+ assert isinstance(x, int)
+ assert isinstance(y, int)
+ return ovfcheck_lshift(x, y)
+
+def op_int_lshift_ovf_val(x, y):
+ assert isinstance(x, int)
+ assert isinstance(y, int)
+ return ovfcheck_lshift(x, y)
+
+def _makefunc2(fn, operator, xtype, ytype=None):
+ if ytype is None:
+ ytype = xtype
+ if '_ovf' in fn:
+ checkfn = 'ovfcheck'
+ elif fn.startswith('op_int_'):
+ 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(x, y):
+ assert isinstance(x, %(xtype)s)
+ assert isinstance(y, %(ytype)s)
+ %(code)s
+ """ % locals()).compile() in globals()
+
+_makefunc2('op_int_add_ovf', '+', '(int, llmemory.AddressOffset)')
+_makefunc2('op_int_mul_ovf', '*', '(int, llmemory.AddressOffset)', 'int')
+_makefunc2('op_int_sub_ovf', '-', 'int')
+_makefunc2('op_int_floordiv_ovf', '//', 'int')
+_makefunc2('op_int_floordiv_zer', '//', 'int')
+_makefunc2('op_int_floordiv_ovf_zer', '//', 'int')
+_makefunc2('op_int_mod_ovf', '%', 'int')
+_makefunc2('op_int_mod_zer', '%', 'int')
+_makefunc2('op_int_mod_ovf_zer', '%', 'int')
+_makefunc2('op_int_lshift_val', '<<', 'int')
+_makefunc2('op_int_rshift_val', '>>', 'int')
+
+_makefunc2('op_uint_floordiv_zer', '//', 'r_uint')
+_makefunc2('op_uint_mod_zer', '%', 'r_uint')
+_makefunc2('op_uint_lshift_val', '<<', 'r_uint')
+_makefunc2('op_uint_rshift_val', '>>', 'r_uint')
+
+_makefunc2('op_llong_floordiv_zer', '//', 'r_longlong')
+_makefunc2('op_llong_mod_zer', '%', 'r_longlong')
+_makefunc2('op_llong_lshift_val', '<<', 'r_longlong')
+_makefunc2('op_llong_rshift_val', '>>', 'r_longlong')
+
+_makefunc2('op_ullong_floordiv_zer', '//', 'r_ulonglong')
+_makefunc2('op_ullong_mod_zer', '%', 'r_ulonglong')
+_makefunc2('op_ullong_lshift_val', '<<', 'r_ulonglong')
+_makefunc2('op_ullong_rshift_val', '>>', 'r_ulonglong')
+
+def op_int_add_nonneg_ovf(x, y):
+ if isinstance(y, int):
+ assert y >= 0
+ return op_int_add_ovf(x, y)
+
+def op_cast_float_to_int(f):
+ assert type(f) is float
+ return ovfcheck(int(f))
+
+# ____________________________________________________________
def get_op_impl(opname):
# get the op_xxx() function from the globals above
Modified: pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/test/test_lloperation.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/test/test_lloperation.py (original)
+++ pypy/branch/jit-hotpath/pypy/rpython/lltypesystem/test/test_lloperation.py Thu Mar 20 18:34:24 2008
@@ -48,7 +48,7 @@
def test_llinterp_complete():
for opname, llop in LL_OPERATIONS.items():
- if llop.canfold:
+ if llop.tryfold:
continue
if opname.startswith('gc_x_'):
continue # ignore experimental stuff
More information about the Pypy-commit
mailing list