[pypy-commit] pypy online-transforms: make it possible to register transformers

rlamy noreply at buildbot.pypy.org
Wed Oct 15 22:59:35 CEST 2014


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: online-transforms
Changeset: r73970:39658f95ae7f
Date: 2014-10-15 21:59 +0100
http://bitbucket.org/pypy/pypy/changeset/39658f95ae7f/

Log:	make it possible to register transformers

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,
@@ -705,6 +706,12 @@
     def setslice(self, s_start, s_stop, s_iterable):
         return self._emulate_call('__setslice__', s_start, s_stop, s_iterable)
 
+ at 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)]
+
+
 class __extend__(SomeBuiltin):
     def call(self, args, implicit_init=False):
         args_s, kwds = args.unpack()
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,8 +106,13 @@
     def get_can_only_throw(self, annotator):
         return None
 
+    def get_transformer(self, *args_s):
+        return lambda *args: None
+
     def transform(self, annotator):
-        pass
+        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
@@ -188,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
@@ -219,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)
@@ -606,15 +658,6 @@
         return ArgumentsForTranslation.fromshape(args_s[0].const,
                                                 list(args_s[1:]))
 
-def transform_len(hlop, annotator):
-    from rpython.annotator.model import SomeInstance
-    s_arg = annotator.annotation(hlop.args[0])
-    if isinstance(s_arg, SomeInstance):
-        get_len = op.getattr(hlop.args[0], const('__len__'))
-        return [get_len, op.simple_call(get_len.result)]
-
-op.len.transform = transform_len
-
 
 # Other functions that get directly translated to SpaceOperators
 func2op[type] = op.type


More information about the pypy-commit mailing list