[pypy-commit] pypy less-stringly-ops: replace SpaceOperators with subclasses of SpaceOperation
rlamy
noreply at buildbot.pypy.org
Mon Aug 19 23:15:09 CEST 2013
Author: Ronan Lamy <ronan.lamy at 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
More information about the pypy-commit
mailing list