Author: Ronan Lamy <ronan.l...@gmail.com>
Branch: 
Changeset: r76264:4b7d6f8bc860
Date: 2015-03-07 01:57 +0000
http://bitbucket.org/pypy/pypy/changeset/4b7d6f8bc860/

Log:    merge branch 'online-transforms-2'

diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -399,12 +399,22 @@
 
     def flowin(self, graph, block):
         try:
-            for i, op in enumerate(block.operations):
+            i = 0
+            while i < len(block.operations):
+                op = block.operations[i]
                 self.bookkeeper.enter((graph, block, i))
                 try:
+                    new_ops = op.transform(self)
+                    if new_ops is not None:
+                        block.operations[i:i+1] = new_ops
+                        if not new_ops:
+                            continue
+                        new_ops[-1].result = op.result
+                        op = new_ops[0]
                     self.consider_op(op)
                 finally:
                     self.bookkeeper.leave()
+                i += 1
 
         except BlockedInference as e:
             if e.op is block.raising_op:
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -2,7 +2,6 @@
 Binary operations between SomeValues.
 """
 
-import operator
 from rpython.tool.pairtype import pair, pairtype
 from rpython.annotator.model import (
     SomeObject, SomeInteger, SomeBool, s_Bool, SomeString, SomeChar, SomeList,
@@ -14,7 +13,7 @@
     read_can_only_throw, add_knowntypedata,
     merge_knowntypedata,)
 from rpython.annotator.bookkeeper import immutablevalue
-from rpython.flowspace.model import Variable, Constant
+from rpython.flowspace.model import Variable, Constant, const
 from rpython.flowspace.operation import op
 from rpython.rlib import rarithmetic
 from rpython.annotator.model import AnnotatorError
@@ -689,12 +688,16 @@
             return super(thistype, pair(ins1, ins2)).improve()
 
 
-class __extend__(pairtype(SomeInstance, SomeObject)):
-    def getitem((s_ins, s_idx)):
-        return s_ins._emulate_call("__getitem__", s_idx)
+@op.getitem.register_transform(SomeInstance, SomeObject)
+def getitem_SomeInstance(annotator, v_ins, v_idx):
+    get_getitem = op.getattr(v_ins, const('__getitem__'))
+    return [get_getitem, op.simple_call(get_getitem.result, v_idx)]
 
-    def setitem((s_ins, s_idx), s_value):
-        return s_ins._emulate_call("__setitem__", s_idx, s_value)
+@op.setitem.register_transform(SomeInstance, SomeObject)
+def setitem_SomeInstance(annotator, v_ins, v_idx, v_value):
+    get_setitem = op.getattr(v_ins, const('__setitem__'))
+    return [get_setitem,
+            op.simple_call(get_setitem.result, v_idx, v_value)]
 
 
 class __extend__(pairtype(SomeIterator, SomeIterator)):
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -5,6 +5,7 @@
 from __future__ import absolute_import
 
 from rpython.flowspace.operation import op
+from rpython.flowspace.model import const
 from rpython.annotator.model import (SomeObject, SomeInteger, SomeBool,
     SomeString, SomeChar, SomeList, SomeDict, SomeTuple, SomeImpossibleValue,
     SomeUnicodeCodePoint, SomeInstance, SomeBuiltin, SomeBuiltinMethod,
@@ -686,27 +687,33 @@
         if not self.can_be_None:
             s.const = True
 
-    def _emulate_call(self, meth_name, *args_s):
-        bk = getbookkeeper()
-        s_attr = self._true_getattr(meth_name)
-        # record for calltables
-        bk.emulate_pbc_call(bk.position_key, s_attr, args_s)
-        return s_attr.call(simple_args(args_s))
+@op.len.register_transform(SomeInstance)
+def len_SomeInstance(annotator, v_arg):
+    get_len = op.getattr(v_arg, const('__len__'))
+    return [get_len, op.simple_call(get_len.result)]
 
-    def iter(self):
-        return self._emulate_call('__iter__')
+@op.iter.register_transform(SomeInstance)
+def iter_SomeInstance(annotator, v_arg):
+    get_iter = op.getattr(v_arg, const('__iter__'))
+    return [get_iter, op.simple_call(get_iter.result)]
 
-    def next(self):
-        return self._emulate_call('next')
+@op.next.register_transform(SomeInstance)
+def next_SomeInstance(annotator, v_arg):
+    get_next = op.getattr(v_arg, const('next'))
+    return [get_next, op.simple_call(get_next.result)]
 
-    def len(self):
-        return self._emulate_call('__len__')
+@op.getslice.register_transform(SomeInstance)
+def getslice_SomeInstance(annotator, v_obj, v_start, v_stop):
+    get_getslice = op.getattr(v_obj, const('__getslice__'))
+    return [get_getslice, op.simple_call(get_getslice.result, v_start, v_stop)]
 
-    def getslice(self, s_start, s_stop):
-        return self._emulate_call('__getslice__', s_start, s_stop)
 
-    def setslice(self, s_start, s_stop, s_iterable):
-        return self._emulate_call('__setslice__', s_start, s_stop, s_iterable)
+@op.setslice.register_transform(SomeInstance)
+def setslice_SomeInstance(annotator, v_obj, v_start, v_stop, v_iterable):
+    get_setslice = op.getattr(v_obj, const('__setslice__'))
+    return [get_setslice,
+            op.simple_call(get_setslice.result, v_start, v_stop, v_iterable)]
+
 
 class __extend__(SomeBuiltin):
     def call(self, args, implicit_init=False):
diff --git a/rpython/flowspace/operation.py b/rpython/flowspace/operation.py
--- a/rpython/flowspace/operation.py
+++ b/rpython/flowspace/operation.py
@@ -57,8 +57,10 @@
             setattr(op, cls.opname, cls)
         if cls.dispatch == 1:
             cls._registry = {}
+            cls._transform = {}
         elif cls.dispatch == 2:
             cls._registry = DoubleDispatchRegistry()
+            cls._transform = DoubleDispatchRegistry()
 
 
 class HLOperation(SpaceOperation):
@@ -104,6 +106,14 @@
     def get_can_only_throw(self, annotator):
         return None
 
+    def get_transformer(self, *args_s):
+        return lambda *args: None
+
+    def transform(self, annotator):
+        args_s = [annotator.annotation(arg) for arg in self.args]
+        transformer = self.get_transformer(*args_s)
+        return transformer(annotator, *self.args)
+
 class PureOperation(HLOperation):
     pure = True
 
@@ -185,6 +195,37 @@
         except AttributeError:
             return cls._dispatch(type(s_arg))
 
+    @classmethod
+    def get_specialization(cls, s_arg, *_ignored):
+        try:
+            impl = getattr(s_arg, cls.opname)
+
+            def specialized(annotator, arg, *other_args):
+                return impl(*[annotator.annotation(x) for x in other_args])
+            try:
+                specialized.can_only_throw = impl.can_only_throw
+            except AttributeError:
+                pass
+            return specialized
+        except AttributeError:
+            return cls._dispatch(type(s_arg))
+
+    @classmethod
+    def register_transform(cls, Some_cls):
+        def decorator(func):
+            cls._transform[Some_cls] = func
+            return func
+        return decorator
+
+    @classmethod
+    def get_transformer(cls, s_arg, *_ignored):
+        for c in type(s_arg).__mro__:
+            try:
+                return cls._transform[c]
+            except KeyError:
+                pass
+        return lambda *args: None
+
 
 class DoubleDispatchMixin(object):
     dispatch = 2
@@ -216,6 +257,20 @@
         spec = type(self).get_specialization(*args_s)
         return read_can_only_throw(spec, args_s[0], args_s[1])
 
+    @classmethod
+    def register_transform(cls, Some1, Some2):
+        def decorator(func):
+            cls._transform[Some1, Some2] = func
+            return func
+        return decorator
+
+    @classmethod
+    def get_transformer(cls, s_arg1, s_arg2, *_ignored):
+        try:
+            return cls._transform[type(s_arg1), type(s_arg2)]
+        except KeyError:
+            return lambda *args: None
+
 
 def add_operator(name, arity, dispatch=None, pyfunc=None, pure=False, 
ovf=False):
     operator_func = getattr(operator, name, None)
diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py
--- a/rpython/rtyper/rclass.py
+++ b/rpython/rtyper/rclass.py
@@ -820,40 +820,6 @@
         vinst, = hop.inputargs(self)
         return hop.genop('ptr_nonzero', [vinst], resulttype=Bool)
 
-    def _emulate_call(self, hop, meth_name):
-        vinst = hop.args_v[0]
-        clsdef = hop.args_s[0].classdef
-        s_unbound_attr = clsdef.find_attribute(meth_name).getvalue()
-        s_attr = clsdef.lookup_filter(s_unbound_attr, meth_name,
-                                      hop.args_s[0].flags)
-        # does that even happen?
-        assert not s_attr.is_constant()
-        if '__iter__' in self.allinstancefields:
-            raise Exception("__iter__ on instance disallowed")
-        r_method = self.rtyper.getrepr(s_attr)
-        r_method.get_method_from_instance(self, vinst, hop.llops)
-        hop2 = hop.copy()
-        hop2.spaceop = op.simple_call(*hop.spaceop.args)
-        hop2.spaceop.result = hop.spaceop.result
-        hop2.args_r[0] = r_method
-        hop2.args_s[0] = s_attr
-        return hop2.dispatch()
-
-    def rtype_iter(self, hop):
-        return self._emulate_call(hop, '__iter__')
-
-    def rtype_next(self, hop):
-        return self._emulate_call(hop, 'next')
-
-    def rtype_getslice(self, hop):
-        return self._emulate_call(hop, "__getslice__")
-
-    def rtype_setslice(self, hop):
-        return self._emulate_call(hop, "__setslice__")
-
-    def rtype_len(self, hop):
-        return self._emulate_call(hop, "__len__")
-
     def ll_str(self, i):  # doesn't work for non-gc classes!
         from rpython.rtyper.lltypesystem.ll_str import ll_int2hex
         from rpython.rlib.rarithmetic import r_uint
@@ -1023,14 +989,6 @@
             return hop.gendirectcall(ll_isinstance, v_obj, v_cls)
 
 
-class __extend__(pairtype(InstanceRepr, Repr)):
-    def rtype_getitem((r_ins, r_obj), hop):
-        return r_ins._emulate_call(hop, "__getitem__")
-
-    def rtype_setitem((r_ins, r_obj), hop):
-        return r_ins._emulate_call(hop, "__setitem__")
-
-
 class __extend__(pairtype(InstanceRepr, InstanceRepr)):
     def convert_from_to((r_ins1, r_ins2), v, llops):
         # which is a subclass of which?
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to