Author: Ronan Lamy <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit