Commits

Ronan Lamy committed d35c47e

Don't use unaryop.UNARY_OPERATIONS in annrpython.py

  • Participants
  • Parent commits d3bc5f2
  • Branches annotator

Comments (0)

Files changed (2)

rpython/annotator/annrpython.py

 from rpython.flowspace.model import (Variable, Constant, FunctionGraph,
                                       c_last_exception, checkgraph)
 from rpython.translator import simplify, transform
-from rpython.annotator import model as annmodel, signature, unaryop, binaryop
+from rpython.annotator import model as annmodel, signature, binaryop
 from rpython.annotator.bookkeeper import Bookkeeper
 
 import py
                 arg2 = self.binding(op.args[1])
                 binop = getattr(pair(arg1, arg2), op.opname, None)
                 can_only_throw = annmodel.read_can_only_throw(binop, arg1, arg2)
-            elif op.opname in unaryop.UNARY_OPERATIONS:
+            elif op.dispatch == 1:
                 arg1 = self.binding(op.args[0])
                 opname = op.opname
                 if opname == 'contains': opname = 'op_contains'
         return self.bookkeeper.newdict()
 
 
-def _register_unary():
-    d = {}
-    for opname in unaryop.UNARY_OPERATIONS:
-        fnname = 'consider_op_' + opname
-        exec py.code.Source("""
-def consider_op_%s(self, arg, *args):
-    return arg.%s(*args)
-""" % (opname, opname)).compile() in globals(), d
-        setattr(RPythonAnnotator, fnname, d[fnname])
-
 def _register_binary():
     d = {}
     for opname in binaryop.BINARY_OPERATIONS:
         setattr(RPythonAnnotator, fnname, d[fnname])
 
 # register simple operations handling
-_register_unary()
 _register_binary()
 
 

rpython/flowspace/operation.py

         ovf.offset = self.offset
         return ovf
 
+class SingleDispatchMixin(object):
+    dispatch = 1
+    def consider(self, annotator, arg, *other_args):
+        impl = getattr(arg, self.opname)
+        return impl(*other_args)
+
 
 def add_operator(name, arity, dispatch=None, pyfunc=None, pure=False, ovf=False):
     operator_func = getattr(operator, name, None)
+    if dispatch == 1:
+        bases = [SingleDispatchMixin]
+    else:
+        bases = []
     if ovf:
         assert pure
         base_cls = OverflowingOperation
         base_cls = PureOperation
     else:
         base_cls = HLOperation
-    cls = HLOperationMeta(name, (base_cls,), {'opname': name, 'arity': arity,
+    bases.append(base_cls)
+    cls = HLOperationMeta(name, tuple(bases), {'opname': name, 'arity': arity,
                                               'canraise': [],
                                               'dispatch': dispatch})
     if pyfunc is not None:
         self.offset = -1
 
 
-class Iter(HLOperation):
+class Iter(SingleDispatchMixin, HLOperation):
     opname = 'iter'
     arity = 1
-    dispatch = 1
     can_overflow = False
     canraise = []
     pyfunc = staticmethod(iter)
             if isinstance(iterable, unrolling_iterable):
                 return const(iterable.get_unroller())
 
-class Next(HLOperation):
+class Next(SingleDispatchMixin, HLOperation):
     opname = 'next'
     arity = 1
-    dispatch = 1
     can_overflow = False
     canraise = []
     pyfunc = staticmethod(next)
         frame.guessexception([StopIteration, RuntimeError], force=True)
         return w_item
 
-class GetAttr(HLOperation):
+class GetAttr(SingleDispatchMixin, HLOperation):
     opname = 'getattr'
     arity = 2
-    dispatch = 1
     can_overflow = False
     canraise = []
     pyfunc = staticmethod(getattr)
         # *any* exception for non-builtins
         return [Exception]
 
-class SimpleCall(CallOp):
+class SimpleCall(SingleDispatchMixin, CallOp):
     opname = 'simple_call'
-    dispatch = 1
 
-class CallArgs(CallOp):
+class CallArgs(SingleDispatchMixin, CallOp):
     opname = 'call_args'
-    dispatch = 1
 
 # Other functions that get directly translated to SpaceOperators
 func2op[type] = op.type