Author: Ronan Lamy <ronan.l...@gmail.com> Branch: less-stringly-ops Changeset: r66235:5a1ff23cec22 Date: 2013-08-09 10:08 +0100 http://bitbucket.org/pypy/pypy/changeset/5a1ff23cec22/
Log: replace SpaceOperators with subclasses of SpaceOperation diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py --- a/rpython/flowspace/flowcontext.py +++ b/rpython/flowspace/flowcontext.py @@ -451,11 +451,10 @@ spaceop.offset = self.last_instr recorder.append(spaceop) - def do_op(self, operator, *args_w): - op = operator(*args_w) + def do_op(self, op): self.record(op) - if operator.canraise: - self.guessexception(operator.canraise) + if op.canraise: + self.guessexception(op.canraise) return op.result def guessexception(self, exceptions): diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -247,7 +247,7 @@ if w_obj in self.not_really_const: const_w = self.not_really_const[w_obj] if w_name not in const_w: - return self.frame.do_op(op.getattr, w_obj, w_name) + return self.frame.do_op(op.getattr(w_obj, w_name)) if w_obj.foldable() and w_name.foldable(): obj, name = w_obj.value, w_name.value try: @@ -261,7 +261,7 @@ return const(result) except WrapException: pass - return self.frame.do_op(op.getattr, w_obj, w_name) + return self.frame.do_op(op.getattr(w_obj, w_name)) def isinstance_w(self, w_obj, w_type): return self.is_true(self.isinstance(w_obj, w_type)) @@ -280,7 +280,7 @@ if w_module in self.not_really_const: const_w = self.not_really_const[w_module] if w_name not in const_w: - return self.frame.do_op(op.getattr, w_module, w_name) + return self.frame.do_op(op.getattr(w_module, w_name)) try: return const(getattr(w_module.value, w_name.value)) except AttributeError: @@ -355,14 +355,14 @@ raise FlowingError(self.frame, const(message)) return const(value) -def make_op(oper): +def make_op(cls): def generic_operator(self, *args): - return oper.eval(self.frame, *args) + return cls(*args).eval(self.frame) return generic_operator -for oper in op.__dict__.values(): - if getattr(FlowObjSpace, oper.name, None) is None: - setattr(FlowObjSpace, oper.name, make_op(oper)) +for cls in op.__dict__.values(): + if getattr(FlowObjSpace, cls.opname, None) is None: + setattr(FlowObjSpace, cls.opname, make_op(cls)) 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 @@ -7,7 +7,8 @@ import __future__ import operator from rpython.tool.sourcetools import compile2 -from rpython.flowspace.model import Constant, WrapException, const, Variable +from rpython.flowspace.model import (Constant, WrapException, const, Variable, + SpaceOperation) from rpython.flowspace.specialcase import register_flow_sc class _OpHolder(object): pass @@ -15,55 +16,50 @@ func2op = {} -class SpaceOperator(object): +class HLOperation(SpaceOperation): pure = False - def __init__(self, name, arity, symbol, pyfunc, can_overflow=False): - self.name = name - self.arity = arity - self.symbol = symbol - self.pyfunc = pyfunc - self.can_overflow = can_overflow - self.canraise = [] + def __init__(self, *args): + self.args = list(args) + self.result = Variable() + self.offset = -1 - def make_sc(self): + @classmethod + def make_sc(cls): def sc_operator(space, args_w): - if len(args_w) != self.arity: - if self is op.pow and len(args_w) == 2: + if len(args_w) != cls.arity: + if cls is op.pow and len(args_w) == 2: args_w = args_w + [Constant(None)] - elif self is op.getattr and len(args_w) == 3: + elif cls is op.getattr and len(args_w) == 3: return space.frame.do_operation('simple_call', Constant(getattr), *args_w) else: raise Exception("should call %r with exactly %d arguments" % ( - self.name, self.arity)) + cls.opname, cls.arity)) # completely replace the call with the underlying # operation and its limited implicit exceptions semantic - return getattr(space, self.name)(*args_w) + return getattr(space, cls.opname)(*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") - return frame.do_op(self, *args_w) + def eval(self, frame): + if len(self.args) != self.arity: + raise TypeError(self.opname + " got the wrong number of arguments") + return frame.do_op(self) - def __call__(self, *args_w): - return SpaceOperation(self.name, args_w, Variable()) - -class PureOperator(SpaceOperator): +class PureOperation(HLOperation): pure = True - def eval(self, frame, *args_w): - if len(args_w) != self.arity: - raise TypeError(self.name + " got the wrong number of arguments") + def eval(self, frame): + if len(self.args) != self.arity: + raise TypeError(self.opname + " 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] + if all(w_arg.foldable() for w_arg in self.args): + args = [w_arg.value for w_arg in self.args] # 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) + self.opname, tuple(args), type(e), e) raise FlowingError(frame, msg) else: # don't try to constant-fold operations giving a 'long' @@ -73,7 +69,7 @@ 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: + elif self.opname == 'getslice' and type(result) is list: pass # otherwise, fine else: @@ -83,23 +79,26 @@ # type cannot sanely appear in flow graph, # store operation with variable result instead pass - return frame.do_op(self, *args_w) + return frame.do_op(self) def add_operator(name, arity, symbol, pyfunc=None, pure=False, ovf=False): operator_func = getattr(operator, name, None) - cls = PureOperator if pure else SpaceOperator - oper = cls(name, arity, symbol, pyfunc, can_overflow=ovf) - setattr(op, name, oper) + base_cls = PureOperation if pure else HLOperation + cls = type(name, (base_cls,), {'opname': name, 'arity': arity, + 'can_overflow': ovf, 'canraise': []}) + setattr(op, name, cls) if pyfunc is not None: - func2op[pyfunc] = oper + func2op[pyfunc] = cls if operator_func: - func2op[operator_func] = oper - if pyfunc is None: - oper.pyfunc = operator_func + func2op[operator_func] = cls + if pyfunc is not None: + cls.pyfunc = staticmethod(pyfunc) + elif operator_func is not None: + cls.pyfunc = staticmethod(operator_func) if ovf: from rpython.rlib.rarithmetic import ovfcheck - ovf_func = lambda *args: ovfcheck(oper.pyfunc(*args)) + ovf_func = lambda *args: ovfcheck(cls.pyfunc(*args)) add_operator(name + '_ovf', arity, symbol, pyfunc=ovf_func) # ____________________________________________________________ @@ -315,7 +314,7 @@ oper = getattr(op, name) lis = oper.canraise if exc in lis: - raise ValueError, "your list is causing duplication!" + raise ValueError("your list is causing duplication!") lis.append(exc) assert exc in op_appendices _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit