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