Author: Ronan Lamy <ronan.l...@gmail.com> Branch: less-stringly-ops Changeset: r66226:ef6bddfa2279 Date: 2013-08-09 05:57 +0100 http://bitbucket.org/pypy/pypy/changeset/ef6bddfa2279/
Log: Turn make_op() into the .eval method of SpaceOperator diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -386,61 +386,14 @@ raise FlowingError(self.frame, const(message)) return const(value) -def make_impure_op(oper): - def generic_operator(self, *args_w): - if len(args_w) != oper.arity: - raise TypeError(oper.name + " got the wrong number of arguments") - w_result = self.frame.do_operation_with_implicit_exceptions(oper.name, *args_w) - return w_result - return generic_operator - def make_op(oper): - """Add function operation to the flow space.""" - name = oper.name - func = oper.pyfunc - - def generic_operator(self, *args_w): - assert len(args_w) == oper.arity, name + " got the wrong number of arguments" - args = [] - if all(w_arg.foldable() for w_arg in args_w): - args = [w_arg.value for w_arg in args_w] - # All arguments are constants: call the operator now - try: - result = func(*args) - except Exception, e: - etype = e.__class__ - msg = "%s%r always raises %s: %s" % ( - name, tuple(args), etype, e) - raise FlowingError(self.frame, msg) - else: - # don't try to constant-fold operations giving a 'long' - # result. The result is probably meant to be sent to - # an intmask(), but the 'long' constant confuses the - # annotator a lot. - if oper.can_overflow and type(result) is long: - pass - # don't constant-fold getslice on lists, either - elif name == 'getslice' and type(result) is list: - pass - # otherwise, fine - else: - try: - return self.wrap(result) - except WrapException: - # type cannot sanely appear in flow graph, - # store operation with variable result instead - pass - w_result = self.frame.do_operation_with_implicit_exceptions(name, *args_w) - return w_result + def generic_operator(self, *args): + return oper.eval(self.frame, *args) return generic_operator for oper in operation.op.__dict__.values(): if getattr(FlowObjSpace, oper.name, None) is None: - if oper.pure: - op_method = make_op(oper) - else: - op_method = make_impure_op(oper) - setattr(FlowObjSpace, oper.name, op_method) + setattr(FlowObjSpace, oper.name, make_op(oper)) def build_flow(func, space=FlowObjSpace()): diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py --- a/rpython/flowspace/operation.py +++ b/rpython/flowspace/operation.py @@ -8,7 +8,7 @@ import operator from rpython.tool.sourcetools import compile2 from rpython.rlib.rarithmetic import ovfcheck -from rpython.flowspace.model import Constant, const +from rpython.flowspace.model import Constant, WrapException, const class _OpHolder(object): pass op = _OpHolder() @@ -40,9 +40,50 @@ return getattr(space, self.name)(*args_w) return sc_operator + def eval(self, frame, *args_w): + if len(args_w) != self.arity: + raise TypeError(self.name + " got the wrong number of arguments") + w_result = frame.do_operation_with_implicit_exceptions(self.name, *args_w) + return w_result + class PureOperator(SpaceOperator): pure = True + def eval(self, frame, *args_w): + if len(args_w) != self.arity: + raise TypeError(self.name + " got the wrong number of arguments") + args = [] + if all(w_arg.foldable() for w_arg in args_w): + args = [w_arg.value for w_arg in args_w] + # All arguments are constants: call the operator now + try: + result = self.pyfunc(*args) + except Exception as e: + from rpython.flowspace.flowcontext import FlowingError + msg = "%s%r always raises %s: %s" % ( + self.name, tuple(args), type(e), e) + raise FlowingError(frame, msg) + else: + # don't try to constant-fold operations giving a 'long' + # result. The result is probably meant to be sent to + # an intmask(), but the 'long' constant confuses the + # annotator a lot. + if self.can_overflow and type(result) is long: + pass + # don't constant-fold getslice on lists, either + elif self.name == 'getslice' and type(result) is list: + pass + # otherwise, fine + else: + try: + return const(result) + except WrapException: + # type cannot sanely appear in flow graph, + # store operation with variable result instead + pass + w_result = frame.do_operation_with_implicit_exceptions(self.name, *args_w) + return w_result + def add_operator(name, arity, symbol, pyfunc=None, pure=False, ovf=False): operator_func = getattr(operator, name, None) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit