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

Reply via email to