[pypy-commit] pypy less-stringly-ops: hg merge default

rlamy noreply at buildbot.pypy.org
Fri Aug 30 11:25:37 CEST 2013


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: less-stringly-ops
Changeset: r66445:27a51d26264b
Date: 2013-08-30 10:22 +0100
http://bitbucket.org/pypy/pypy/changeset/27a51d26264b/

Log:	hg merge default

diff too long, truncating to 2000 out of 3740 lines

diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -1229,7 +1229,10 @@
         if cvt is not None:
             param = cvt(param)
 
-        param = adapt(param)
+        try:
+            param = adapt(param)
+        except:
+            pass  # And use previous value
 
         if param is None:
             rc = _lib.sqlite3_bind_null(self._statement, idx)
diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -339,9 +339,10 @@
 
 + methods and other class attributes do not change after startup
 + single inheritance is fully supported
-+ simple mixins somewhat work too, but the mixed in class needs a
-  ``_mixin_ = True`` class attribute. isinstance checks against the
-  mixin type will fail when translated.
++ use `rpython.rlib.objectmodel.import_from_mixin(M)` in a class
+  body to copy the whole content of a class `M`.  This can be used
+  to implement mixins: functions and staticmethods are duplicated
+  (the other class attributes are just copied unmodified).
 
 + classes are first-class objects too
 
diff --git a/pypy/doc/getting-started-python.rst b/pypy/doc/getting-started-python.rst
--- a/pypy/doc/getting-started-python.rst
+++ b/pypy/doc/getting-started-python.rst
@@ -57,6 +57,12 @@
      zlib-devel bzip2-devel ncurses-devel expat-devel \
      openssl-devel gc-devel python-sphinx python-greenlet
 
+   On SLES11:
+
+     $ sudo zypper install gcc make python-devel pkg-config \
+     zlib-devel libopenssl-devel libbz2-devel sqlite3-devel \
+     libexpat-devel libffi-devel python-curses
+
    The above command lines are split with continuation characters, giving the necessary dependencies first, then the optional ones.
 
    * ``pkg-config`` (to help us locate libffi files)
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -74,3 +74,4 @@
 .. branch: dotviewer-linewidth
 .. branch: reflex-support
 .. branch: numpypy-inplace-op
+.. branch: rewritten-loop-logging
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -6,6 +6,10 @@
 The following text gives some hints about how to translate the PyPy
 interpreter.
 
+PyPy supports only being translated as a 32bit program, even on
+64bit Windows.  See at the end of this page for what is missing
+for a full 64bit translation.
+
 To build pypy-c you need a C compiler.  Microsoft Visual Studio is
 preferred, but can also use the mingw32 port of gcc.
 
@@ -63,7 +67,7 @@
 INCLUDE, LIB and PATH (for DLLs) environment variables appropriately.
 
 Abridged method (for -Ojit builds using Visual Studio 2008)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Download the versions of all the external packages
 from 
 https://bitbucket.org/pypy/pypy/downloads/local.zip
@@ -112,13 +116,14 @@
     nmake -f makefile.msc
     
 The sqlite3 database library
-~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Download http://www.sqlite.org/2013/sqlite-amalgamation-3071601.zip and extract
 it into a directory under the base directory. Also get 
 http://www.sqlite.org/2013/sqlite-dll-win32-x86-3071601.zip and extract the dll
 into the bin directory, and the sqlite3.def into the sources directory.
 Now build the import library so cffi can use the header and dll::
+
     lib /DEF:sqlite3.def" /OUT:sqlite3.lib"
     copy sqlite3.lib path\to\libs
 
@@ -206,8 +211,86 @@
 March 2012, --cc is not a valid option for pytest.py. However if you set an
 environment variable CC to the compliter exe, testing will use it.
 
-.. _'mingw32 build': http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds
+.. _`mingw32 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds
 .. _`mingw64 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds
 .. _`msys for mingw`: http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/MSYS%20%2832-bit%29   
 .. _`libffi source files`: http://sourceware.org/libffi/
 .. _`RPython translation toolchain`: translation.html
+
+
+What is missing for a full 64-bit translation
+---------------------------------------------
+
+The main blocker is that we assume that the integer type of RPython is
+large enough to (occasionally) contain a pointer value cast to an
+integer.  The simplest fix is to make sure that it is so, but it will
+give the following incompatibility between CPython and PyPy on Win64:
+  
+CPython: ``sys.maxint == 2**32-1, sys.maxsize == 2**64-1``
+
+PyPy: ``sys.maxint == sys.maxsize == 2**64-1``
+
+...and, correspondingly, PyPy supports ints up to the larger value of
+sys.maxint before they are converted to ``long``.  The first decision
+that someone needs to make is if this incompatibility is reasonable.
+
+Assuming that it is, the first thing to do is probably to hack *CPython*
+until it fits this model: replace the field in PyIntObject with a ``long
+long`` field, and change the value of ``sys.maxint``.  This might just
+work, even if half-brokenly: I'm sure you can crash it because of the
+precision loss that undoubtedly occurs everywhere, but try not to. :-)
+
+Such a hacked CPython is what you'll use in the next steps.  We'll call
+it CPython64/64.
+
+It is probably not too much work if the goal is only to get a translated
+PyPy executable, and to run all tests before transaction.  But you need
+to start somewhere, and you should start with some tests in
+rpython/translator/c/test/, like ``test_standalone.py`` and
+``test_newgc.py``: try to have them pass on top of CPython64/64.
+
+Keep in mind that this runs small translations, and some details may go
+wrong.  The most obvious one is to check that it produces C files that
+use the integer type ``Signed`` --- but what is ``Signed`` defined to?
+It should be equal to ``long`` on every other platforms, but on Win64 it
+should be something like ``long long``.
+
+What is more generally needed is to review all the C files in
+rpython/translator/c/src for the word ``long``, because this means a
+32-bit integer even on Win64.  Replace it with ``Signed`` most of the
+times.  You can replace one with the other without breaking anything on
+any other platform, so feel free to.
+
+Then, these two C types have corresponding RPython types: ``rffi.LONG``
+and ``lltype.Signed`` respectively.  The first should really correspond
+to the C ``long``.  Add tests that check that integers casted to one
+type or the other really have 32 and 64 bits respectively, on Win64.
+
+Once these basic tests work, you need to review ``rpython/rlib/`` for
+usages of ``rffi.LONG`` versus ``lltype.Signed``.  The goal would be to
+fix some more ``LONG-versus-Signed`` issues, by fixing the tests --- as
+always run on top of CPython64/64.  Note that there was some early work
+done in ``rpython/rlib/rarithmetic`` with the goal of running all the
+tests on Win64 on the regular CPython, but I think by now that it's a
+bad idea.  Look only at CPython64/64.
+
+The major intermediate goal is to get a translation of PyPy with ``-O2``
+with a minimal set of modules, starting with ``--no-allworkingmodules``;
+you need to use CPython64/64 to run this translation too.  Check
+carefully the warnings of the C compiler at the end.  I think that MSVC
+is "nice" in the sense that by default a lot of mismatches of integer
+sizes are reported as warnings.
+
+Then you need to review ``pypy/module/*/`` for ``LONG-versus-Signed``
+issues.  At some time during this review, we get a working translated
+PyPy on Windows 64 that includes all ``--translationmodules``, i.e.
+everything needed to run translations.  When we are there, the hacked
+CPython64/64 becomes much less important, because we can run future
+translations on top of this translated PyPy.  As soon as we get there,
+please *distribute* the translated PyPy.  It's an essential component
+for anyone else that wants to work on Win64!  We end up with a strange
+kind of dependency --- we need a translated PyPy in order to translate a
+PyPy ---, but I believe it's ok here, as Windows executables are
+supposed to never be broken by newer versions of Windows.
+
+Happy hacking :-)
diff --git a/pypy/interpreter/buffer.py b/pypy/interpreter/buffer.py
--- a/pypy/interpreter/buffer.py
+++ b/pypy/interpreter/buffer.py
@@ -19,7 +19,7 @@
 from pypy.interpreter.typedef import TypeDef
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.error import OperationError
-from rpython.rlib.objectmodel import compute_hash
+from rpython.rlib.objectmodel import compute_hash, import_from_mixin
 from rpython.rlib.rstring import StringBuilder
 
 
@@ -272,8 +272,6 @@
 # ____________________________________________________________
 
 class SubBufferMixin(object):
-    _mixin_ = True
-
     def __init__(self, buffer, offset, size):
         self.buffer = buffer
         self.offset = offset
@@ -297,10 +295,11 @@
                           # out of bounds
         return self.buffer.getslice(self.offset + start, self.offset + stop, step, size)
 
-class SubBuffer(SubBufferMixin, Buffer):
-    pass
+class SubBuffer(Buffer):
+    import_from_mixin(SubBufferMixin)
 
-class RWSubBuffer(SubBufferMixin, RWBuffer):
+class RWSubBuffer(RWBuffer):
+    import_from_mixin(SubBufferMixin)
 
     def setitem(self, index, char):
         self.buffer.setitem(self.offset + index, char)
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -685,7 +685,7 @@
             name='string',
             char='S',
             w_box_type = space.gettypefor(interp_boxes.W_StringBox),
-            alternate_constructors=[space.w_str],
+            alternate_constructors=[space.w_str, space.gettypefor(interp_boxes.W_CharacterBox)],
             aliases=["str"],
         )
         self.w_unicodedtype = W_Dtype(
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -88,13 +88,27 @@
         w_res = W_NDimArray.from_shape(space, res_shape, self.get_dtype(), w_instance=self)
         return loop.getitem_filter(w_res, self, arr)
 
-    def setitem_filter(self, space, idx, val):
+    def setitem_filter(self, space, idx, value):
+        from pypy.module.micronumpy.interp_boxes import Box
+        val = value
         if len(idx.get_shape()) > 1 and idx.get_shape() != self.get_shape():
             raise OperationError(space.w_ValueError,
                                  space.wrap("boolean index array should have 1 dimension"))
         if idx.get_size() > self.get_size():
             raise OperationError(space.w_ValueError,
                                  space.wrap("index out of range for array"))
+        idx_iter = idx.create_iter(self.get_shape())
+        size = loop.count_all_true_iter(idx_iter, self.get_shape(), idx.get_dtype())
+        if len(val.get_shape()) > 0 and val.get_shape()[0] > 1 and size > val.get_shape()[0]:
+            raise OperationError(space.w_ValueError, space.wrap("NumPy boolean array indexing assignment "
+                                                                "cannot assign %d input values to "
+                                                                "the %d output values where the mask is true" % (val.get_shape()[0],size)))
+        if val.get_shape() == [1]:
+            box = val.descr_getitem(space, space.wrap(0))
+            assert isinstance(box, Box)
+            val = W_NDimArray(scalar.Scalar(val.get_dtype(), box))
+        elif val.get_shape() == [0]:
+            val.implementation.dtype = self.implementation.dtype
         loop.setitem_filter(self, idx, val)
 
     def _prepare_array_index(self, space, w_index):
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -318,23 +318,27 @@
         lefti.next()
     return result
 
-count_all_true_driver = jit.JitDriver(name = 'numpy_count',
-                                      greens = ['shapelen', 'dtype'],
-                                      reds = 'auto')
 
 def count_all_true(arr):
-    s = 0
     if arr.is_scalar():
         return arr.get_dtype().itemtype.bool(arr.get_scalar_value())
     iter = arr.create_iter()
-    shapelen = len(arr.get_shape())
-    dtype = arr.get_dtype()
+    return count_all_true_iter(iter, arr.get_shape(), arr.get_dtype())
+
+count_all_true_iter_driver = jit.JitDriver(name = 'numpy_count',
+                                      greens = ['shapelen', 'dtype'],
+                                      reds = 'auto')
+def count_all_true_iter(iter, shape, dtype):
+    s = 0
+    shapelen = len(shape)
+    dtype = dtype
     while not iter.done():
-        count_all_true_driver.jit_merge_point(shapelen=shapelen, dtype=dtype)
+        count_all_true_iter_driver.jit_merge_point(shapelen=shapelen, dtype=dtype)
         s += iter.getitem_bool()
         iter.next()
     return s
 
+
 getitem_filter_driver = jit.JitDriver(name = 'numpy_getitem_bool',
                                       greens = ['shapelen', 'arr_dtype',
                                                 'index_dtype'],
@@ -370,7 +374,7 @@
 
 def setitem_filter(arr, index, value):
     arr_iter = arr.create_iter()
-    index_iter = index.create_iter()
+    index_iter = index.create_iter(arr.get_shape())
     value_iter = value.create_iter()
     shapelen = len(arr.get_shape())
     index_dtype = index.get_dtype()
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -778,6 +778,11 @@
         from numpypy import unicode_
         assert isinstance(unicode_(3), unicode)
 
+    def test_character_dtype(self):
+        from numpypy import array, character
+        x = array([["A", "B"], ["C", "D"]], character)
+        assert (x == [["A", "B"], ["C", "D"]]).all()
+
 class AppTestRecordDtypes(BaseNumpyAppTest):
     spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
     def test_create(self):
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -1922,6 +1922,28 @@
         a = numpy.arange(10.).reshape((5, 2))[::2]
         assert (loads(dumps(a)) == a).all()
 
+    def test_string_filling(self):
+        import numpypy as numpy
+        a = numpy.empty((10,10), dtype='c1')
+        a.fill(12)
+        assert (a == '1').all()
+
+    def test_boolean_indexing(self):
+        import numpypy as np
+        a = np.zeros((1, 3))
+        b = np.array([True])
+
+        assert (a[b] == a).all()
+
+        a[b] = 1.
+
+        assert (a == [[1., 1., 1.]]).all()
+
+    def test_boolean_array(self):
+        import numpypy as np
+        a = np.ndarray([1], dtype=bool)
+        assert a[0] == True
+
 class AppTestMultiDim(BaseNumpyAppTest):
     def test_init(self):
         import numpypy
@@ -2329,6 +2351,21 @@
         a[a & 1 == 0] = 15
         assert (a == [[15, 1], [15, 5], [15, 9]]).all()
 
+    def test_array_indexing_bool_specialcases(self):
+        from numpypy import arange, array
+        a = arange(6)
+        try:
+            a[a < 3] = [1, 2]
+            assert False, "Should not work"
+        except ValueError:
+            pass
+        a = arange(6)
+        a[a > 3] = array([15])
+        assert (a == [0, 1, 2, 3, 15, 15]).all()
+        a = arange(6).reshape(3, 2)
+        a[a & 1 == 1] = []  # here, Numpy sticks garbage into the array
+        assert a.shape == (3, 2)
+
     def test_copy_kwarg(self):
         from numpypy import array
         x = array([1, 2, 3])
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -257,6 +257,7 @@
 
     def test_rint(self):
         from numpypy import array, complex, rint, isnan
+        import sys
 
         nnan, nan, inf, ninf = float('-nan'), float('nan'), float('inf'), float('-inf')
 
@@ -271,6 +272,8 @@
         assert rint(complex(inf, 1.5)) == complex(inf, 2.)
         assert rint(complex(0.5, inf)) == complex(0., inf)
 
+        assert rint(sys.maxint) > 0.0
+
     def test_sign(self):
         from numpypy import array, sign, dtype
 
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -308,13 +308,6 @@
         return min(v1, v2)
 
     @simple_unary_op
-    def rint(self, v):
-        if isfinite(v):
-            return rfloat.round_double(v, 0, half_even=True)
-        else:
-            return v
-
-    @simple_unary_op
     def ones_like(self, v):
         return 1
 
@@ -322,6 +315,10 @@
     def zeros_like(self, v):
         return 0
 
+    @raw_unary_op
+    def rint(self, v):
+        float64 = Float64()
+        return float64.rint(float64.box(v))
 
 class NonNativePrimitive(Primitive):
     _mixin_ = True
@@ -1036,6 +1033,25 @@
         else:
             return v1 + v2
 
+    @simple_unary_op
+    def rint(self, v):
+        x = float(v)
+        if isfinite(x):
+            import math
+            y = math.floor(x)
+            r = x - y
+
+            if r > 0.5:
+                y += 1.0
+
+            if r == 0.5:
+                r = y - 2.0 * math.floor(0.5 * y)
+                if r == 1.0:
+                    y += 1.0
+            return y
+        else:
+            return x
+
 class NonNativeFloat(NonNativePrimitive, Float):
     _mixin_ = True
 
@@ -1748,12 +1764,16 @@
             arr.storage[i] = arg[i]
         return interp_boxes.W_StringBox(arr,  0, arr.dtype)
 
-    @jit.unroll_safe
     def store(self, arr, i, offset, box):
         assert isinstance(box, interp_boxes.W_StringBox)
         # XXX simplify to range(box.dtype.get_size()) ?
+        return self._store(arr.storage, i, offset, box)
+
+    @jit.unroll_safe
+    def _store(self, storage, i, offset, box):
+        assert isinstance(box, interp_boxes.W_StringBox)
         for k in range(min(self.size, box.arr.size-offset)):
-            arr.storage[k + i] = box.arr.storage[k + offset]
+            storage[k + i] = box.arr.storage[k + offset]
 
     def read(self, arr, i, offset, dtype=None):
         if dtype is None:
@@ -1843,6 +1863,11 @@
             arr.storage[j] = '\x00'
         return interp_boxes.W_StringBox(arr,  0, arr.dtype)
 
+    def fill(self, storage, width, box, start, stop, offset):
+        from pypy.module.micronumpy.arrayimpl.concrete import ConcreteArrayNotOwning
+        for i in xrange(start, stop, width):
+            self._store(storage, i, offset, box)
+
 NonNativeStringType = StringType
 
 class UnicodeType(BaseType, BaseStringType):
diff --git a/pypy/module/test_lib_pypy/test_sqlite3.py b/pypy/module/test_lib_pypy/test_sqlite3.py
--- a/pypy/module/test_lib_pypy/test_sqlite3.py
+++ b/pypy/module/test_lib_pypy/test_sqlite3.py
@@ -228,3 +228,18 @@
     cur = con.cursor()
     cur.execute(u'SELECT 1 as méil')
     assert cur.description[0][0] == u"méil".encode('utf-8')
+
+def test_adapter_exception(con):
+    def cast(obj):
+        raise ZeroDivisionError
+
+    _sqlite3.register_adapter(int, cast)
+    try:
+        cur = con.cursor()
+        cur.execute("select ?", (4,))
+        val = cur.fetchone()[0]
+        # Adapter error is ignored, and parameter is passed as is.
+        assert val == 4
+        assert type(val) is int
+    finally:
+        del _sqlite3.adapters[(int, _sqlite3.PrepareProtocol)]
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -121,7 +121,7 @@
         greens=['w_type'], reds='auto')
 
 class DescrOperation(object):
-    _mixin_ = True
+    # This is meant to be a *mixin*.
 
     def is_data_descr(space, w_obj):
         return space.lookup(w_obj, '__set__') is not None
@@ -867,12 +867,12 @@
         elif _arity == 2 and len(_specialnames) == 2:
             #print "binop", _specialnames
             _impl_maker = _make_binop_impl
-        elif _arity == 1 and len(_specialnames) == 1:
+        elif _arity == 1 and len(_specialnames) == 1 and _name != 'int':
             #print "unaryop", _specialnames
             _impl_maker = _make_unaryop_impl
         if _impl_maker:
             setattr(DescrOperation,_name,_impl_maker(_symbol,_specialnames))
-        elif _name not in ['is_', 'id','type','issubtype',
+        elif _name not in ['is_', 'id','type','issubtype', 'int',
                            # not really to be defined in DescrOperation
                            'ord', 'unichr', 'unicode']:
             raise Exception, "missing def for operation %s" % _name
diff --git a/pypy/objspace/std/builtinshortcut.py b/pypy/objspace/std/builtinshortcut.py
--- a/pypy/objspace/std/builtinshortcut.py
+++ b/pypy/objspace/std/builtinshortcut.py
@@ -131,6 +131,7 @@
                 w_obj = w_res
 
         # general case fallback
-        return DescrOperation.is_true(space, w_obj)
+        return _DescrOperation_is_true(space, w_obj)
 
+    _DescrOperation_is_true = DescrOperation.is_true.im_func
     space.is_true = is_true
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -1276,10 +1276,7 @@
             return _all_contained_in(space, self, w_other)
         return space.w_False
 
-    def descr_ne(self, space, w_other):
-        if not _is_set_like(w_other):
-            return space.w_NotImplemented
-        return space.not_(space.eq(self, w_other))
+    descr_ne = negate(descr_eq)
 
     def descr_lt(self, space, w_other):
         if not _is_set_like(w_other):
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -1,20 +1,22 @@
+"""The builtin int implementation
+
+In order to have the same behavior running on CPython, and after RPython
+translation this module uses rarithmetic.ovfcheck to explicitly check
+for overflows, something CPython does not do anymore.
+"""
+
+from rpython.rlib import jit
+from rpython.rlib.rarithmetic import LONG_BIT, is_valid_int, ovfcheck, r_uint
+from rpython.rlib.rbigint import rbigint
+
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std import newformat
 from pypy.objspace.std.inttype import W_AbstractIntObject
-from pypy.objspace.std.model import registerimplementation, W_Object
+from pypy.objspace.std.model import W_Object, registerimplementation
 from pypy.objspace.std.multimethod import FailedToImplementArgs
 from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.objspace.std.register_all import register_all
-from rpython.rlib import jit
-from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, r_uint, is_valid_int
-from rpython.rlib.rbigint import rbigint
 
-"""
-In order to have the same behavior running
-on CPython, and after RPython translation we use ovfcheck
-from rarithmetic to explicitly check for overflows,
-something CPython does not do anymore.
-"""
 
 class W_IntObject(W_AbstractIntObject):
     __slots__ = 'intval'
@@ -22,28 +24,29 @@
 
     from pypy.objspace.std.inttype import int_typedef as typedef
 
-    def __init__(w_self, intval):
+    def __init__(self, intval):
         assert is_valid_int(intval)
-        w_self.intval = intval
+        self.intval = intval
 
-    def __repr__(w_self):
-        """ representation for debugging purposes """
-        return "%s(%d)" % (w_self.__class__.__name__, w_self.intval)
+    def __repr__(self):
+        """representation for debugging purposes"""
+        return "%s(%d)" % (self.__class__.__name__, self.intval)
 
-    def unwrap(w_self, space):
-        return int(w_self.intval)
+    def unwrap(self, space):
+        return int(self.intval)
     int_w = unwrap
 
-    def uint_w(w_self, space):
-        intval = w_self.intval
+    def uint_w(self, space):
+        intval = self.intval
         if intval < 0:
-            raise OperationError(space.w_ValueError,
-                                 space.wrap("cannot convert negative integer to unsigned"))
+            raise OperationError(
+                space.w_ValueError,
+                space.wrap("cannot convert negative integer to unsigned"))
         else:
             return r_uint(intval)
 
-    def bigint_w(w_self, space):
-        return rbigint.fromint(w_self.intval)
+    def bigint_w(self, space):
+        return rbigint.fromint(self.intval)
 
     def float_w(self, space):
         return float(self.intval)
@@ -144,7 +147,8 @@
     x = float(w_int1.intval)
     y = float(w_int2.intval)
     if y == 0.0:
-        raise FailedToImplementArgs(space.w_ZeroDivisionError, space.wrap("float division"))
+        raise FailedToImplementArgs(space.w_ZeroDivisionError,
+                                    space.wrap("float division"))
     return space.wrap(x / y)
 
 def mod__Int_Int(space, w_int1, w_int2):
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -1,13 +1,17 @@
+"""The builtin long implementation"""
+
 import sys
+
+from rpython.rlib.rbigint import rbigint
+
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std import model, newformat
-from pypy.objspace.std.model import registerimplementation, W_Object
+from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.longtype import W_AbstractLongObject, long_typedef
+from pypy.objspace.std.model import W_Object, registerimplementation
+from pypy.objspace.std.multimethod import FailedToImplementArgs
+from pypy.objspace.std.noneobject import W_NoneObject
 from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.multimethod import FailedToImplementArgs
-from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.noneobject import W_NoneObject
-from rpython.rlib.rbigint import rbigint
-from pypy.objspace.std.longtype import long_typedef, W_AbstractLongObject
 
 
 class W_LongObject(W_AbstractLongObject):
@@ -16,8 +20,8 @@
 
     typedef = long_typedef
 
-    def __init__(w_self, l):
-        w_self.num = l # instance of rbigint
+    def __init__(self, l):
+        self.num = l # instance of rbigint
 
     def fromint(space, intval):
         return W_LongObject(rbigint.fromint(intval))
@@ -49,16 +53,16 @@
     fromrarith_int._annspecialcase_ = "specialize:argtype(0)"
     fromrarith_int = staticmethod(fromrarith_int)
 
-    def int_w(w_self, space):
+    def int_w(self, space):
         try:
-            return w_self.num.toint()
+            return self.num.toint()
         except OverflowError:
             raise OperationError(space.w_OverflowError, space.wrap(
                 "long int too large to convert to int"))
 
-    def uint_w(w_self, space):
+    def uint_w(self, space):
         try:
-            return w_self.num.touint()
+            return self.num.touint()
         except ValueError:
             raise OperationError(space.w_ValueError, space.wrap(
                 "cannot convert negative integer to unsigned int"))
@@ -66,8 +70,8 @@
             raise OperationError(space.w_OverflowError, space.wrap(
                 "long int too large to convert to unsigned int"))
 
-    def bigint_w(w_self, space):
-        return w_self.num
+    def bigint_w(self, space):
+        return self.num
 
     def float_w(self, space):
         return self.tofloat(space)
@@ -324,7 +328,8 @@
             sys.maxint == 2147483647)
 
 # binary ops
-for opname in ['add', 'sub', 'mul', 'div', 'floordiv', 'truediv', 'mod', 'divmod', 'lshift']:
+for opname in ['add', 'sub', 'mul', 'div', 'floordiv', 'truediv', 'mod',
+               'divmod', 'lshift']:
     exec compile("""
 def %(opname)s_ovr__Int_Int(space, w_int1, w_int2):
     if recover_with_smalllong(space) and %(opname)r != 'truediv':
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -10,7 +10,7 @@
 from rpython.rlib.objectmodel import instantiate, specialize, is_annotation_constant
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.rlib.rarithmetic import base_int, widen, is_valid_int
-from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib.objectmodel import we_are_translated, import_from_mixin
 from rpython.rlib import jit
 
 # Object imports
@@ -37,9 +37,10 @@
 from pypy.objspace.std.stringtype import wrapstr
 from pypy.objspace.std.unicodetype import wrapunicode
 
-class StdObjSpace(ObjSpace, DescrOperation):
+class StdObjSpace(ObjSpace):
     """The standard object space, implementing a general-purpose object
     library in Restricted Python."""
+    import_from_mixin(DescrOperation)
 
     def initialize(self):
         "NOT_RPYTHON: only for initializing the space."
@@ -492,16 +493,19 @@
                                  self.wrap("Expected tuple of length 3"))
         return self.int_w(l_w[0]), self.int_w(l_w[1]), self.int_w(l_w[2])
 
+    _DescrOperation_is_true = is_true
+    _DescrOperation_getattr = getattr
+
     def is_true(self, w_obj):
         # a shortcut for performance
         # NOTE! this method is typically overridden by builtinshortcut.py.
         if type(w_obj) is W_BoolObject:
             return w_obj.boolval
-        return DescrOperation.is_true(self, w_obj)
+        return self._DescrOperation_is_true(w_obj)
 
     def getattr(self, w_obj, w_name):
         if not self.config.objspace.std.getattributeshortcut:
-            return DescrOperation.getattr(self, w_obj, w_name)
+            return self._DescrOperation_getattr(w_obj, w_name)
         # an optional shortcut for performance
 
         w_type = self.type(w_obj)
diff --git a/pypy/objspace/std/util.py b/pypy/objspace/std/util.py
--- a/pypy/objspace/std/util.py
+++ b/pypy/objspace/std/util.py
@@ -9,10 +9,7 @@
         tmp = f(self, space, w_other)
         if tmp is space.w_NotImplemented:
             return space.w_NotImplemented
-        elif tmp is space.w_False:
-            return space.w_True
-        else:
-            return space.w_False
+        return space.newbool(tmp is space.w_False)
     _negator.func_name = 'negate-%s' % f.func_name
     return _negator
 
diff --git a/pypy/tool/gcdump.py b/pypy/tool/gcdump.py
--- a/pypy/tool/gcdump.py
+++ b/pypy/tool/gcdump.py
@@ -29,6 +29,8 @@
         for num, line in enumerate(iter):
             if num == 0:
                 continue
+            if not line:
+                continue
             words = line.split()
             if words[0].startswith('member'):
                 del words[0]
diff --git a/rpython/annotator/annrpython.py b/rpython/annotator/annrpython.py
--- a/rpython/annotator/annrpython.py
+++ b/rpython/annotator/annrpython.py
@@ -5,7 +5,7 @@
 from rpython.tool.ansi_print import ansi_log
 from rpython.tool.pairtype import pair
 from rpython.tool.error import (format_blocked_annotation_error,
-                             AnnotatorError, gather_error, ErrorWrapper)
+                             gather_error, source_lines)
 from rpython.flowspace.model import (Variable, Constant, FunctionGraph,
                                       c_last_exception, checkgraph)
 from rpython.translator import simplify, transform
@@ -18,7 +18,6 @@
 
 FAIL = object()
 
-
 class RPythonAnnotator(object):
     """Block annotator for RPython.
     See description in doc/translation.txt."""
@@ -137,9 +136,7 @@
         checkgraph(flowgraph)
 
         nbarg = len(flowgraph.getargs())
-        if len(inputcells) != nbarg:
-            raise TypeError("%s expects %d args, got %d" %(
-                            flowgraph, nbarg, len(inputcells)))
+        assert len(inputcells) == nbarg # wrong number of args
 
         # register the entry point
         self.addpendinggraph(flowgraph, inputcells)
@@ -160,7 +157,7 @@
             else:
                 return object
         else:
-            raise TypeError, ("Variable or Constant instance expected, "
+            raise TypeError("Variable or Constant instance expected, "
                               "got %r" % (variable,))
 
     def getuserclassdefinitions(self):
@@ -221,7 +218,7 @@
 
             text = format_blocked_annotation_error(self, self.blocked_blocks)
             #raise SystemExit()
-            raise AnnotatorError(text)
+            raise annmodel.AnnotatorError(text)
         for graph in newgraphs:
             v = graph.getreturnvar()
             if v not in self.bindings:
@@ -244,7 +241,7 @@
             #    return annmodel.s_ImpossibleValue
             return self.bookkeeper.immutableconstant(arg)
         else:
-            raise TypeError, 'Variable or Constant expected, got %r' % (arg,)
+            raise TypeError('Variable or Constant expected, got %r' % (arg,))
 
     def typeannotation(self, t):
         return signature.annotation(t, self.bookkeeper)
@@ -383,8 +380,8 @@
         try:
             unions = [annmodel.unionof(c1,c2) for c1, c2 in zip(oldcells,inputcells)]
         except annmodel.UnionError, e:
-            e.args = e.args + (
-                ErrorWrapper(gather_error(self, graph, block, None)),)
+            # Add source code to the UnionError
+            e.source = '\n'.join(source_lines(graph, block, None, long=True))
             raise
         # if the merged cells changed, we must redo the analysis
         if unions != oldcells:
@@ -603,10 +600,9 @@
                 raise BlockedInference(self, op, opindex)
         try:
             resultcell = consider_meth(*argcells)
-        except Exception, e:
+        except annmodel.AnnotatorError as e: # note that UnionError is a subclass
             graph = self.bookkeeper.position_key[0]
-            e.args = e.args + (
-                ErrorWrapper(gather_error(self, graph, block, opindex)),)
+            e.source = gather_error(self, graph, block, opindex)
             raise
         if resultcell is None:
             resultcell = self.noreturnvalue(op)
diff --git a/rpython/annotator/argument.py b/rpython/annotator/argument.py
--- a/rpython/annotator/argument.py
+++ b/rpython/annotator/argument.py
@@ -115,9 +115,7 @@
         elif num_args > co_argcount:
             raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0)
 
-        # if a **kwargs argument is needed, explode
-        if signature.has_kwarg():
-            raise TypeError("Keyword arguments as **kwargs is not supported by RPython")
+        assert not signature.has_kwarg() # XXX should not happen?
 
         # handle keyword arguments
         num_remainingkwds = 0
diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py
--- a/rpython/annotator/binaryop.py
+++ b/rpython/annotator/binaryop.py
@@ -20,7 +20,7 @@
 from rpython.annotator.bookkeeper import getbookkeeper
 from rpython.flowspace.model import Variable, Constant
 from rpython.rlib import rarithmetic
-from rpython.tool.error import AnnotatorError
+from rpython.annotator.model import AnnotatorError
 
 # convenience only!
 def immutablevalue(x):
@@ -243,14 +243,16 @@
 
             if t2 is int:
                 if int2.nonneg == False:
-                    raise UnionError, "Merging %s and a possibly negative int is not allowed" % t1
+                    raise UnionError(int1, int2, "RPython cannot prove that these " + \
+                            "integers are of the same signedness")
                 knowntype = t1
             elif t1 is int:
                 if int1.nonneg == False:
-                    raise UnionError, "Merging %s and a possibly negative int is not allowed" % t2
+                    raise UnionError(int1, int2, "RPython cannot prove that these " + \
+                            "integers are of the same signedness")
                 knowntype = t2
             else:
-                raise UnionError, "Merging these types (%s, %s) is not supported" % (t1, t2)
+                raise UnionError(int1, int2)
         return SomeInteger(nonneg=int1.nonneg and int2.nonneg,
                            knowntype=knowntype)
 
@@ -455,7 +457,7 @@
 class __extend__(pairtype(SomeString, SomeUnicodeString),
                  pairtype(SomeUnicodeString, SomeString)):
     def mod((str, unistring)):
-        raise NotImplementedError(
+        raise AnnotatorError(
             "string formatting mixing strings and unicode not supported")
 
 
@@ -469,7 +471,7 @@
             if (is_unicode and isinstance(s_item, (SomeChar, SomeString)) or
                 is_string and isinstance(s_item, (SomeUnicodeCodePoint,
                                                   SomeUnicodeString))):
-                raise NotImplementedError(
+                raise AnnotatorError(
                     "string formatting mixing strings and unicode not supported")
         getbookkeeper().count('strformat', s_string, s_tuple)
         no_nul = s_string.no_nul
@@ -551,9 +553,9 @@
 
     def union((tup1, tup2)):
         if len(tup1.items) != len(tup2.items):
-            raise UnionError("cannot take the union of a tuple of length %d "
-                             "and a tuple of length %d" % (len(tup1.items),
-                                                           len(tup2.items)))
+            raise UnionError(tup1, tup2, "RPython cannot unify tuples of "
+                    "different length: %d versus %d" % \
+                    (len(tup1.items), len(tup2.items)))
         else:
             unions = [unionof(x,y) for x,y in zip(tup1.items, tup2.items)]
             return SomeTuple(items = unions)
@@ -726,7 +728,8 @@
         else:
             basedef = ins1.classdef.commonbase(ins2.classdef)
             if basedef is None:
-                raise UnionError(ins1, ins2)
+                raise UnionError(ins1, ins2, "RPython cannot unify instances "
+                        "with no common base class")
         flags = ins1.flags
         if flags:
             flags = flags.copy()
@@ -768,7 +771,8 @@
     def union((iter1, iter2)):
         s_cont = unionof(iter1.s_container, iter2.s_container)
         if iter1.variant != iter2.variant:
-            raise UnionError("merging incompatible iterators variants")
+            raise UnionError(iter1, iter2,
+                    "RPython cannot unify incompatible iterator variants")
         return SomeIterator(s_cont, *iter1.variant)
 
 
@@ -778,8 +782,7 @@
         if (bltn1.analyser != bltn2.analyser or
             bltn1.methodname != bltn2.methodname or
             bltn1.s_self is None or bltn2.s_self is None):
-            raise UnionError("cannot merge two different builtin functions "
-                             "or methods:\n  %r\n  %r" % (bltn1, bltn2))
+            raise UnionError(bltn1, bltn2)
         s_self = unionof(bltn1.s_self, bltn2.s_self)
         return SomeBuiltin(bltn1.analyser, s_self, methodname=bltn1.methodname)
 
@@ -976,8 +979,8 @@
 
 class __extend__(pairtype(SomeAddress, SomeObject)):
     def union((s_addr, s_obj)):
-        raise UnionError, "union of address and anything else makes no sense"
+        raise UnionError(s_addr, s_obj)
 
 class __extend__(pairtype(SomeObject, SomeAddress)):
     def union((s_obj, s_addr)):
-        raise UnionError, "union of address and anything else makes no sense"
+        raise UnionError(s_obj, s_addr)
diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py
--- a/rpython/annotator/builtin.py
+++ b/rpython/annotator/builtin.py
@@ -337,7 +337,7 @@
     return SomeAddress()
 
 def unicodedata_decimal(s_uchr):
-    raise TypeError, "unicodedate.decimal() calls should not happen at interp-level"
+    raise TypeError("unicodedate.decimal() calls should not happen at interp-level")
 
 def test(*args):
     return s_Bool
diff --git a/rpython/annotator/classdef.py b/rpython/annotator/classdef.py
--- a/rpython/annotator/classdef.py
+++ b/rpython/annotator/classdef.py
@@ -2,7 +2,7 @@
 Type inference for user-defined classes.
 """
 from rpython.annotator.model import SomePBC, s_ImpossibleValue, unionof
-from rpython.annotator.model import SomeInteger, SomeTuple, SomeString
+from rpython.annotator.model import SomeInteger, SomeTuple, SomeString, AnnotatorError
 from rpython.annotator import description
 
 
@@ -429,7 +429,7 @@
                         result.extend(slots)
         return result
 
-class NoSuchAttrError(Exception):
+class NoSuchAttrError(AnnotatorError):
     """Raised when an attribute is found on a class where __slots__
      or _attrs_ forbits it."""
 
diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py
--- a/rpython/annotator/description.py
+++ b/rpython/annotator/description.py
@@ -6,6 +6,7 @@
 from rpython.annotator.argument import rawshape, ArgErr
 from rpython.tool.sourcetools import valid_identifier, func_with_new_name
 from rpython.tool.pairtype import extendabletype
+from rpython.annotator.model import AnnotatorError
 
 class CallFamily(object):
     """A family of Desc objects that could be called from common call sites.
@@ -261,7 +262,7 @@
         try:
             inputcells = args.match_signature(signature, defs_s)
         except ArgErr, e:
-            raise TypeError("signature mismatch: %s() %s" %
+            raise AnnotatorError("signature mismatch: %s() %s" %
                             (self.name, e.getmsg()))
         return inputcells
 
@@ -678,7 +679,7 @@
                 value = value.__get__(42)
                 classdef = None   # don't bind
             elif isinstance(value, classmethod):
-                raise AssertionError("classmethods are not supported")
+                raise AnnotatorError("classmethods are not supported")
             s_value = self.bookkeeper.immutablevalue(value)
             if classdef is not None:
                 s_value = s_value.bind_callables_under(classdef, name)
diff --git a/rpython/annotator/listdef.py b/rpython/annotator/listdef.py
--- a/rpython/annotator/listdef.py
+++ b/rpython/annotator/listdef.py
@@ -58,7 +58,7 @@
     def merge(self, other):
         if self is not other:
             if getattr(TLS, 'no_side_effects_in_union', 0):
-                raise UnionError("merging list/dict items")
+                raise UnionError(self, other)
 
             if other.dont_change_any_more:
                 if self.dont_change_any_more:
diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py
--- a/rpython/annotator/model.py
+++ b/rpython/annotator/model.py
@@ -676,10 +676,42 @@
 
 # ____________________________________________________________
 
-class UnionError(Exception):
+
+class AnnotatorError(Exception):
+    def __init__(self, msg=None):
+        self.msg = msg
+        self.source = None
+
+    def __str__(self):
+        s = "\n\n%s" % self.msg
+        if self.source is not None:
+            s += "\n\n"
+            s += self.source
+
+        return s
+
+class UnionError(AnnotatorError):
     """Signals an suspicious attempt at taking the union of
     deeply incompatible SomeXxx instances."""
 
+    def __init__(self, s_obj1, s_obj2, msg=None):
+        """
+        This exception expresses the fact that s_obj1 and s_obj2 cannot be unified.
+        The msg paramter is appended to a generic message. This can be used to
+        give the user a little more information.
+        """
+        s = ""
+        if msg is not None:
+            s += "%s\n\n" % msg
+        s += "Offending annotations:\n"
+        s += "  %s\n  %s" % (s_obj1, s_obj2)
+        self.s_obj1 = s_obj1
+        self.s_obj2 = s_obj2
+        self.msg = s
+        self.source = None
+
+    def __repr__(self):
+        return str(self)
 
 def unionof(*somevalues):
     "The most precise SomeValue instance that contains all the values."
diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -228,7 +228,7 @@
         def f():
             return X().meth()
         a = self.RPythonAnnotator()
-        py.test.raises(AssertionError, a.build_types, f,  [])
+        py.test.raises(annmodel.AnnotatorError, a.build_types, f,  [])
 
     def test_methodcall1(self):
         a = self.RPythonAnnotator()
@@ -2539,6 +2539,27 @@
         s = a.build_types(f, [])
         assert s.const == 2
 
+    def test_import_from_mixin(self):
+        class M(object):
+            def f(self):
+                return self.a
+        class I(object):
+            objectmodel.import_from_mixin(M)
+            def __init__(self, i):
+                self.a = i
+        class S(object):
+            objectmodel.import_from_mixin(M)
+            def __init__(self, s):
+                self.a = s
+        def f(n):
+            return (I(n).f(), S("a" * n).f())
+
+        assert f(3) == (3, "aaa")
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [int])
+        assert isinstance(s.items[0], annmodel.SomeInteger)
+        assert isinstance(s.items[1], annmodel.SomeString)
+
     def test___class___attribute(self):
         class Base(object): pass
         class A(Base): pass
@@ -3360,22 +3381,22 @@
             return '%s' % unichr(x)
 
         a = self.RPythonAnnotator()
-        py.test.raises(NotImplementedError, a.build_types, f, [int])
+        py.test.raises(annmodel.AnnotatorError, a.build_types, f, [int])
         def f(x):
             return '%s' % (unichr(x) * 3)
 
         a = self.RPythonAnnotator()
-        py.test.raises(NotImplementedError, a.build_types, f, [int])
+        py.test.raises(annmodel.AnnotatorError, a.build_types, f, [int])
         def f(x):
             return '%s%s' % (1, unichr(x))
 
         a = self.RPythonAnnotator()
-        py.test.raises(NotImplementedError, a.build_types, f, [int])
+        py.test.raises(annmodel.AnnotatorError, a.build_types, f, [int])
         def f(x):
             return '%s%s' % (1, unichr(x) * 15)
 
         a = self.RPythonAnnotator()
-        py.test.raises(NotImplementedError, a.build_types, f, [int])
+        py.test.raises(annmodel.AnnotatorError, a.build_types, f, [int])
 
 
     def test_strformatting_tuple(self):
@@ -3413,7 +3434,7 @@
             return [1, 2, 3][s:e]
 
         a = self.RPythonAnnotator()
-        py.test.raises(TypeError, "a.build_types(f, [int, int])")
+        py.test.raises(annmodel.AnnotatorError, "a.build_types(f, [int, int])")
         a.build_types(f, [annmodel.SomeInteger(nonneg=True),
                           annmodel.SomeInteger(nonneg=True)])
         def f(x):
@@ -4002,6 +4023,101 @@
         a = self.RPythonAnnotator()
         assert not a.build_types(fn, [int]).nonneg
 
+    def test_unionerror_attrs(self):
+        def f(x):
+            if x < 10:
+                return 1
+            else:
+                return "bbb"
+        a = self.RPythonAnnotator()
+
+        with py.test.raises(annmodel.UnionError) as exc:
+            a.build_types(f, [int])
+
+        the_exc = exc.value
+        s_objs = set([type(the_exc.s_obj1), type(the_exc.s_obj2)])
+
+        assert s_objs == set([annmodel.SomeInteger, annmodel.SomeString])
+
+    def test_unionerror_tuple_size(self):
+        def f(x):
+            if x < 10:
+                return (1, )
+            else:
+                return (1, 2)
+        a = self.RPythonAnnotator()
+
+        with py.test.raises(annmodel.UnionError) as exc:
+            a.build_types(f, [int])
+
+        assert "RPython cannot unify tuples of different length: 2 versus 1" in exc.value.msg
+
+    def test_unionerror_signedness(self):
+        def f(x):
+            if x < 10:
+                return r_uint(99)
+            else:
+                return -1
+        a = self.RPythonAnnotator()
+
+        with py.test.raises(annmodel.UnionError) as exc:
+            a.build_types(f, [int])
+
+        assert ("RPython cannot prove that these integers are of the "
+                "same signedness" in exc.value.msg)
+
+    def test_unionerror_instance(self):
+        class A(object): pass
+        class B(object): pass
+
+        def f(x):
+            if x < 10:
+                return A()
+            else:
+                return B()
+        a = self.RPythonAnnotator()
+
+        with py.test.raises(annmodel.UnionError) as exc:
+            a.build_types(f, [int])
+
+        assert ("RPython cannot unify instances with no common base class" 
+                in exc.value.msg)
+
+    def test_unionerror_iters(self):
+
+        def f(x):
+            d = { 1 : "a", 2 : "b" }
+            if x < 10:
+                return d.iterkeys()
+            else:
+                return d.itervalues()
+        a = self.RPythonAnnotator()
+
+        with py.test.raises(annmodel.UnionError) as exc:
+            a.build_types(f, [int])
+
+        assert ("RPython cannot unify incompatible iterator variants" in 
+                exc.value.msg)
+
+    def test_variable_getattr(self):
+        class A(object): pass
+        def f(y):
+            a = A()
+            return getattr(a, y)
+        a = self.RPythonAnnotator()
+        with py.test.raises(annmodel.AnnotatorError) as exc:
+            a.build_types(f, [str])
+        assert ("variable argument to getattr" in exc.value.msg)
+
+    def test_bad_call(self):
+        def f(x):
+            return x()
+        a = self.RPythonAnnotator()
+        with py.test.raises(annmodel.AnnotatorError) as exc:
+            a.build_types(f, [str])
+        assert ("Cannot prove that the object is callable" in exc.value.msg)
+
+
 def g(n):
     return [0, 1, 2, n]
 
diff --git a/rpython/annotator/test/test_argument.py b/rpython/annotator/test/test_argument.py
--- a/rpython/annotator/test/test_argument.py
+++ b/rpython/annotator/test/test_argument.py
@@ -77,10 +77,6 @@
         new_args = args.unmatch_signature(sig, data)
         assert args.unpack() == new_args.unpack()
 
-        args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7})
-        sig = Signature(['a', 'b', 'c'], None, 'kw')
-        py.test.raises(TypeError, args.match_signature, sig, [2, 3])
-
     def test_rawshape(self):
         space = DummySpace()
         args = make_arguments_for_translation(space, [1,2,3])
diff --git a/rpython/annotator/test/test_model.py b/rpython/annotator/test/test_model.py
--- a/rpython/annotator/test/test_model.py
+++ b/rpython/annotator/test/test_model.py
@@ -2,6 +2,7 @@
 
 from rpython.annotator.model import *
 from rpython.annotator.listdef import ListDef
+from rpython.translator.translator import TranslationContext
 
 
 listdef1 = ListDef(None, SomeTuple([SomeInteger(nonneg=True), SomeString()]))
@@ -174,6 +175,28 @@
     assert f2.contains(f1)
     assert f1.contains(f2)
 
+def compile_function(function, annotation=[]):
+    t = TranslationContext()
+    t.buildannotator().build_types(function, annotation)
+
+class AAA(object):
+    pass
+
+def test_blocked_inference1():
+    def blocked_inference():
+        return AAA().m()
+
+    py.test.raises(AnnotatorError, compile_function, blocked_inference)
+
+def test_blocked_inference2():
+    def blocked_inference():
+        a = AAA()
+        b = a.x
+        return b
+
+    py.test.raises(AnnotatorError, compile_function, blocked_inference)
+
+
 if __name__ == '__main__':
     for name, value in globals().items():
         if name.startswith('test_'):
diff --git a/rpython/annotator/unaryop.py b/rpython/annotator/unaryop.py
--- a/rpython/annotator/unaryop.py
+++ b/rpython/annotator/unaryop.py
@@ -14,7 +14,7 @@
 from rpython.annotator.bookkeeper import getbookkeeper
 from rpython.annotator import builtin
 from rpython.annotator.binaryop import _clone ## XXX where to put this?
-from rpython.tool.error import AnnotatorError
+from rpython.annotator.model import AnnotatorError
 
 # convenience only!
 def immutablevalue(x):
@@ -81,8 +81,7 @@
         return r
 
     def hash(obj):
-        raise TypeError, ("cannot use hash() in RPython; "
-                          "see objectmodel.compute_xxx()")
+        raise AnnotatorError("cannot use hash() in RPython")
 
     def str(obj):
         getbookkeeper().count('str', obj)
@@ -155,9 +154,7 @@
         return obj.call(getbookkeeper().build_args("call_args", args_s))
 
     def call(obj, args, implicit_init=False):
-        #raise Exception, "cannot follow call_args%r" % ((obj, args),)
-        getbookkeeper().warning("cannot follow call(%r, %r)" % (obj, args))
-        return SomeObject()
+        raise AnnotatorError("Cannot prove that the object is callable")
 
     def op_contains(obj, s_element):
         return s_Bool
@@ -338,10 +335,10 @@
 
 def check_negative_slice(s_start, s_stop):
     if isinstance(s_start, SomeInteger) and not s_start.nonneg:
-        raise TypeError("slicing: not proven to have non-negative start")
+        raise AnnotatorError("slicing: not proven to have non-negative start")
     if isinstance(s_stop, SomeInteger) and not s_stop.nonneg and \
            getattr(s_stop, 'const', 0) != -1:
-        raise TypeError("slicing: not proven to have non-negative stop")
+        raise AnnotatorError("slicing: not proven to have non-negative stop")
 
 
 class __extend__(SomeDict):
@@ -526,10 +523,10 @@
 class __extend__(SomeUnicodeString):
     def method_encode(uni, s_enc):
         if not s_enc.is_constant():
-            raise TypeError("Non-constant encoding not supported")
+            raise AnnotatorError("Non-constant encoding not supported")
         enc = s_enc.const
         if enc not in ('ascii', 'latin-1', 'utf-8'):
-            raise TypeError("Encoding %s not supported for unicode" % (enc,))
+            raise AnnotatorError("Encoding %s not supported for unicode" % (enc,))
         return SomeString()
     method_encode.can_only_throw = [UnicodeEncodeError]
 
@@ -559,10 +556,10 @@
 
     def method_decode(str, s_enc):
         if not s_enc.is_constant():
-            raise TypeError("Non-constant encoding not supported")
+            raise AnnotatorError("Non-constant encoding not supported")
         enc = s_enc.const
         if enc not in ('ascii', 'latin-1', 'utf-8'):
-            raise TypeError("Encoding %s not supported for strings" % (enc,))
+            raise AnnotatorError("Encoding %s not supported for strings" % (enc,))
         return SomeUnicodeString()
     method_decode.can_only_throw = [UnicodeDecodeError]
 
@@ -650,7 +647,7 @@
         if s_attr.is_constant() and isinstance(s_attr.const, str):
             attr = s_attr.const
             return ins._true_getattr(attr)
-        return SomeObject()
+        raise AnnotatorError("A variable argument to getattr is not RPython")
     getattr.can_only_throw = []
 
     def setattr(ins, s_attr, s_value):
@@ -726,7 +723,7 @@
 
     def setattr(pbc, s_attr, s_value):
         if not pbc.isNone():
-            raise AnnotatorError("setattr on %r" % pbc)
+            raise AnnotatorError("Cannot modify attribute of a pre-built constant")
 
     def call(pbc, args):
         bookkeeper = getbookkeeper()
@@ -748,7 +745,8 @@
             # whose length is the constant 0; so let's tentatively answer 0.
             return immutablevalue(0)
         else:
-            return SomeObject()    # len() on a pbc? no chance
+            # This should probably never happen
+            raise AnnotatorError("Cannot call len on a pbc")
 
 # annotation of low-level types
 from rpython.annotator.model import SomePtr, SomeLLADTMeth
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -21,8 +21,9 @@
     frame = None
 
     def __str__(self):
-        msg = ['-+' * 30]
+        msg = ["\n"]
         msg += map(str, self.args)
+        msg += [""]
         msg += source_lines(self.frame.graph, None, offset=self.frame.last_instr)
         return "\n".join(msg)
 
@@ -290,7 +291,7 @@
 
 _unsupported_ops = [
     ('BINARY_POWER', "a ** b"),
-    ('BUILD_CLASS', 'creating new classes'),
+    ('BUILD_CLASS', 'defining classes inside functions'),
     ('EXEC_STMT', 'exec statement'),
     ('STOP_CODE', '???'),
     ('STORE_NAME', 'modifying globals'),
diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -571,7 +571,8 @@
             self.mc.BL(self.stack_check_slowpath, c=c.HI)      # call if ip > lr
 
     # cpu interface
-    def assemble_loop(self, loopname, inputargs, operations, looptoken, log):
+    def assemble_loop(self, logger, loopname, inputargs, operations, looptoken,
+                      log):
         clt = CompiledLoopToken(self.cpu, looptoken.number)
         looptoken.compiled_loop_token = clt
         clt._debug_nbargs = len(inputargs)
@@ -620,6 +621,9 @@
                     'loop.asm')
 
         ops_offset = self.mc.ops_offset
+        if logger is not None:
+            logger.log_loop(inputargs, operations, 0, "rewritten",
+                            name=loopname, ops_offset=ops_offset)
         self.teardown()
 
         debug_start("jit-backend-addr")
@@ -644,8 +648,8 @@
             frame_depth = max(frame_depth, target_frame_depth)
         return frame_depth
 
-    def assemble_bridge(self, faildescr, inputargs, operations,
-                                                    original_loop_token, log):
+    def assemble_bridge(self, logger, faildescr, inputargs, operations,
+                        original_loop_token, log):
         if not we_are_translated():
             # Arguments should be unique
             assert len(set(inputargs)) == len(inputargs)
@@ -694,6 +698,9 @@
                           frame_depth_no_fixed_size + JITFRAME_FIXED_SIZE)
         self.fixup_target_tokens(rawstart)
         self.update_frame_depth(frame_depth)
+        if logger:
+            logger.log_bridge(inputargs, operations, "rewritten",
+                              ops_offset=ops_offset)
         self.teardown()
 
         debug_bridge(descr_number, rawstart, codeendpos)
diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py
--- a/rpython/jit/backend/arm/runner.py
+++ b/rpython/jit/backend/arm/runner.py
@@ -56,17 +56,18 @@
     def finish_once(self):
         self.assembler.finish_once()
 
-    def compile_loop(self, inputargs, operations, looptoken,
+    def compile_loop(self, logger, inputargs, operations, looptoken,
                                                     log=True, name=''):
-        return self.assembler.assemble_loop(name, inputargs, operations,
-                                                    looptoken, log=log)
+        return self.assembler.assemble_loop(logger, name, inputargs, operations,
+                                            looptoken, log=log)
 
-    def compile_bridge(self, faildescr, inputargs, operations,
+    def compile_bridge(self, logger, faildescr, inputargs, operations,
                                        original_loop_token, log=True):
         clt = original_loop_token.compiled_loop_token
         clt.compiling_a_bridge()
-        return self.assembler.assemble_bridge(faildescr, inputargs, operations,
-                                                original_loop_token, log=log)
+        return self.assembler.assemble_bridge(logger, faildescr, inputargs,
+                                              operations,
+                                              original_loop_token, log=log)
 
     def clear_latest_values(self, count):
         setitem = self.assembler.fail_boxes_ptr.setitem
diff --git a/rpython/jit/backend/arm/test/test_generated.py b/rpython/jit/backend/arm/test/test_generated.py
--- a/rpython/jit/backend/arm/test/test_generated.py
+++ b/rpython/jit/backend/arm/test/test_generated.py
@@ -40,7 +40,7 @@
         looptoken = JitCellToken()
         operations[2].setfailargs([v12, v8, v3, v2, v1, v11])
         operations[3].setfailargs([v9, v6, v10, v2, v8, v5, v1, v4])
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == 0
@@ -92,7 +92,7 @@
         operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1])
         operations[-1].setfailargs([v7, v1, v2])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == 105
@@ -136,7 +136,7 @@
         operations[-1].setfailargs([v5, v2, v1, v10, v3, v8, v4, v6])
 
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 2
@@ -179,7 +179,7 @@
         operations[5].setfailargs([])
         operations[-1].setfailargs([v8, v2, v6, v5, v7, v1, v10])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == -29
@@ -223,7 +223,7 @@
         looptoken = JitCellToken()
         operations[5].setfailargs([])
         operations[-1].setfailargs([v1, v4, v10, v8, v7, v3])
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [1073741824 , 95 , -16 , 5 , 92 , 12 , 32 , 17 , 37 , -63]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_int_value(deadframe, 0) == 1073741824
@@ -280,7 +280,7 @@
         operations[9].setfailargs([v10, v13])
         operations[-1].setfailargs([v8, v10, v6, v3, v2, v9])
         args = [32 , 41 , -9 , 12 , -18 , 46 , 15 , 17 , 10 , 12]
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 3
         assert cpu.get_int_value(deadframe, 0) == 12
@@ -328,7 +328,7 @@
         operations[8].setfailargs([v5, v9])
         operations[-1].setfailargs([v4, v10, v6, v5, v9, v7])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [-8 , 0 , 62 , 35 , 16 , 9 , 30 , 581610154 , -1 , 738197503]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 2
@@ -378,7 +378,7 @@
         operations[-2].setfailargs([v9, v4, v10, v11, v14])
         operations[-1].setfailargs([v10, v8, v1, v6, v4])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [-39 , -18 , 1588243114 , -9 , -4 , 1252698794 , 0 , 715827882 , -15 , 536870912]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 1
@@ -433,7 +433,7 @@
         operations[9].setfailargs([v5, v7, v12, v14, v2, v13, v8])
         operations[-1].setfailargs([v1, v2, v9])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [0 , -2 , 24 , 1 , -4 , 13 , -95 , 33 , 2 , -44]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 3
@@ -475,7 +475,7 @@
         operations[2].setfailargs([v10, v3, v6, v11, v9, v2])
         operations[-1].setfailargs([v8, v2, v10, v6, v7, v9, v5, v4])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [3 , -5 , 1431655765 , 47 , 12 , 1789569706 , 15 , 939524096 , 16 , -43]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 1
@@ -524,7 +524,7 @@
         operations[-1].setfailargs([v2, v3, v5, v7, v10, v8, v9])
         operations[4].setfailargs([v14])
         looptoken = JitCellToken()
-        cpu.compile_loop(inputargs, operations, looptoken)
+        cpu.compile_loop(None, inputargs, operations, looptoken)
         args = [14 , -20 , 18 , -2058005163 , 6 , 1 , -16 , 11 , 0 , 19]
         deadframe = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_descr(deadframe).identifier == 1
diff --git a/rpython/jit/backend/arm/test/test_regalloc2.py b/rpython/jit/backend/arm/test/test_regalloc2.py
--- a/rpython/jit/backend/arm/test/test_regalloc2.py
+++ b/rpython/jit/backend/arm/test/test_regalloc2.py
@@ -24,7 +24,7 @@
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.compile_loop(None, inputargs, operations, looptoken)
     deadframe = cpu.execute_token(looptoken, 9)
     assert cpu.get_int_value(deadframe, 0) == (9 >> 3)
     assert cpu.get_int_value(deadframe, 1) == (~18)
@@ -48,7 +48,7 @@
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.compile_loop(None, inputargs, operations, looptoken)
     deadframe = cpu.execute_token(looptoken, -10)
     assert cpu.get_int_value(deadframe, 0) == 0
     assert cpu.get_int_value(deadframe, 1) == -1000
@@ -145,7 +145,7 @@
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.compile_loop(None, inputargs, operations, looptoken)
     args = [-13 , 10 , 10 , 8 , -8 , -16 , -18 , 46 , -12 , 26]
     deadframe = cpu.execute_token(looptoken, *args)
     assert cpu.get_int_value(deadframe, 0) == 0
@@ -252,7 +252,7 @@
     cpu = CPU(None, None)
     cpu.setup_once()
     looptoken = JitCellToken()
-    cpu.compile_loop(inputargs, operations, looptoken)
+    cpu.compile_loop(None, inputargs, operations, looptoken)
     args = [17 , -20 , -6 , 6 , 1 , 13 , 13 , 9 , 49 , 8]
     deadframe = cpu.execute_token(looptoken, *args)
     assert cpu.get_int_value(deadframe, 0) == 0
diff --git a/rpython/jit/backend/arm/test/test_runner.py b/rpython/jit/backend/arm/test/test_runner.py
--- a/rpython/jit/backend/arm/test/test_runner.py
+++ b/rpython/jit/backend/arm/test/test_runner.py
@@ -75,7 +75,7 @@
             ResOperation(rop.FINISH, [inp[1]], None, descr=BasicFinalDescr(1)),
             ]
         operations[-2].setfailargs(out)
-        cpu.compile_loop(inp, operations, looptoken)
+        cpu.compile_loop(None, inp, operations, looptoken)
         args = [i for i in range(1, 15)]
         deadframe = self.cpu.execute_token(looptoken, *args)
         output = [self.cpu.get_int_value(deadframe, i - 1) for i in range(1, 15)]
@@ -117,9 +117,9 @@
         i1 = int_sub(i0, 1)
         finish(i1)
         ''')
-        self.cpu.compile_loop(loop2.inputargs, loop2.operations, lt2)
-        self.cpu.compile_loop(loop3.inputargs, loop3.operations, lt3)
-        self.cpu.compile_loop(loop1.inputargs, loop1.operations, lt1)
+        self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, lt2)
+        self.cpu.compile_loop(None, loop3.inputargs, loop3.operations, lt3)
+        self.cpu.compile_loop(None, loop1.inputargs, loop1.operations, lt1)
         df = self.cpu.execute_token(lt1, 10)
         assert self.cpu.get_int_value(df, 0) == 7
 
@@ -214,7 +214,7 @@
             ops = "".join(ops)
             loop = parse(ops)
             looptoken = JitCellToken()
-            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+            self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
             ARGS = [lltype.Signed] * numargs
             RES = lltype.Signed
             args = [i+1 for i in range(numargs)]
@@ -246,7 +246,7 @@
         try:
             self.cpu.assembler.set_debug(True)
             looptoken = JitCellToken()
-            self.cpu.compile_loop(ops.inputargs, ops.operations, looptoken)
+            self.cpu.compile_loop(None, ops.inputargs, ops.operations, looptoken)
             self.cpu.execute_token(looptoken, 0)
             # check debugging info
             struct = self.cpu.assembler.loop_run_counters[0]
@@ -280,7 +280,7 @@
         faildescr = BasicFailDescr(2)
         loop = parse(ops, self.cpu, namespace=locals())
         looptoken = JitCellToken()
-        info = self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        info = self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
         ops2 = """
         [i0, f1]
         i1 = same_as(i0)
@@ -293,7 +293,7 @@
         """
         loop2 = parse(ops2, self.cpu, namespace=locals())
         looptoken2 = JitCellToken()
-        info = self.cpu.compile_loop(loop2.inputargs, loop2.operations, looptoken2)
+        info = self.cpu.compile_loop(None, loop2.inputargs, loop2.operations, looptoken2)
 
         deadframe = self.cpu.execute_token(looptoken, -9, longlong.getfloatstorage(-13.5))
         res = longlong.getrealfloat(self.cpu.get_float_value(deadframe, 0))
diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -183,7 +183,8 @@
         self.stats = stats or MiniStats()
         self.vinfo_for_tests = kwds.get('vinfo_for_tests', None)
 
-    def compile_loop(self, inputargs, operations, looptoken, log=True, name=''):
+    def compile_loop(self, logger, inputargs, operations, looptoken, log=True,
+                     name=''):
         clt = model.CompiledLoopToken(self, looptoken.number)
         looptoken.compiled_loop_token = clt
         lltrace = LLTrace(inputargs, operations)
@@ -191,7 +192,7 @@
         clt._llgraph_alltraces = [lltrace]
         self._record_labels(lltrace)
 
-    def compile_bridge(self, faildescr, inputargs, operations,
+    def compile_bridge(self, logger, faildescr, inputargs, operations,
                        original_loop_token, log=True):
         clt = original_loop_token.compiled_loop_token
         clt.compiling_a_bridge()
diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_gc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py
@@ -676,7 +676,7 @@
                         'checkdescr': checkdescr,
                         'fielddescr': cpu.fielddescrof(S, 'x')})
         token = JitCellToken()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         p0 = lltype.malloc(S, zero=True)
         p1 = lltype.malloc(S)
         p2 = lltype.malloc(S)
@@ -715,7 +715,7 @@
             'calldescr': checkdescr,
         })
         token = JitCellToken()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         S = self.S
         s = lltype.malloc(S)
         cpu.execute_token(token, 1, s)
@@ -743,7 +743,7 @@
         token = JitCellToken()
         cpu.gc_ll_descr.init_nursery(20)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         arg = longlong.getfloatstorage(2.3)
         frame = cpu.execute_token(token, arg)
         ofs = cpu.get_baseofs_of_frame_field()
@@ -770,7 +770,7 @@
         cpu.gc_ll_descr.collections = [[0, sizeof.size]]
         cpu.gc_ll_descr.init_nursery(2 * sizeof.size)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         frame = cpu.execute_token(token)
         # now we should be able to track everything from the frame
         frame = lltype.cast_opaque_ptr(JITFRAMEPTR, frame)
@@ -821,7 +821,7 @@
         token = JitCellToken()
         cpu.gc_ll_descr.init_nursery(100)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         args = [lltype.nullptr(llmemory.GCREF.TO) for i in range(7)]
         frame = cpu.execute_token(token, 1, *args)
         frame = rffi.cast(JITFRAMEPTR, frame)
@@ -867,7 +867,7 @@
         token = JitCellToken()
         cpu.gc_ll_descr.init_nursery(100)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         frame = lltype.cast_opaque_ptr(JITFRAMEPTR,
                                        cpu.execute_token(token, 1, a))
 
@@ -911,7 +911,7 @@
         token = JitCellToken()
         cpu.gc_ll_descr.init_nursery(100)
         cpu.setup_once()
-        cpu.compile_loop(loop.inputargs, loop.operations, token)
+        cpu.compile_loop(None, loop.inputargs, loop.operations, token)
         frame = lltype.cast_opaque_ptr(JITFRAMEPTR,
                                        cpu.execute_token(token, 1, a))
         assert getmap(frame).count('1') == 4
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
@@ -97,7 +97,7 @@
         loop = self.parse(ops, namespace=namespace)
         self.loop = loop
         looptoken = JitCellToken()
-        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
         arguments = []
         for arg in args:
             if isinstance(arg, int):
@@ -147,7 +147,8 @@
         assert ([box.type for box in bridge.inputargs] ==
                 [box.type for box in guard_op.getfailargs()])
         faildescr = guard_op.getdescr()
-        self.cpu.compile_bridge(faildescr, bridge.inputargs, bridge.operations,
+        self.cpu.compile_bridge(None, faildescr, bridge.inputargs,
+                                bridge.operations,
                                 loop._jitcelltoken)
         return bridge
 
@@ -335,7 +336,7 @@
         '''
         self.interpret(ops, [0, 0, 3, 0])
         assert self.getints(3) == [1, -3, 10]
-        
+
     def test_compare_memory_result_survives(self):
         ops = '''
         [i0, i1, i2, i3]
@@ -409,7 +410,7 @@
 
 
 class TestRegallocCompOps(BaseTestRegalloc):
-    
+
     def test_cmp_op_0(self):
         ops = '''
         [i0, i3]
@@ -575,7 +576,7 @@
 class TestRegAllocCallAndStackDepth(BaseTestRegalloc):
     def setup_class(cls):
         py.test.skip("skip for now, not sure what do we do")
-    
+
     def expected_frame_depth(self, num_call_args, num_pushed_input_args=0):
         # Assumes the arguments are all non-float
         if not self.cpu.IS_64_BIT:
@@ -612,7 +613,7 @@
         ops = '''
         [i0, i1,  i2, i3, i4, i5, i6, i7, i8, i9]
         i10 = call(ConstClass(f1ptr), i0, descr=f1_calldescr)
-        i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr)        
+        i11 = call(ConstClass(f2ptr), i10, i1, descr=f2_calldescr)
         guard_false(i5) [i11, i1,  i2, i3, i4, i5, i6, i7, i8, i9]
         '''
         loop = self.interpret(ops, [4, 7, 9, 9 ,9, 9, 9, 9, 9, 9])
@@ -649,7 +650,7 @@
 
         ops = '''
         [i2, i0, i1]
-        i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)        
+        i3 = call(ConstClass(f2ptr), i2, i1, descr=f2_calldescr)
         guard_false(i0, descr=fdescr2) [i3, i0]
         '''
         bridge = self.attach_bridge(ops, loop, -2)
@@ -676,7 +677,7 @@
 
         ops = '''
         [i2]
-        i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)        
+        i3 = call(ConstClass(f1ptr), i2, descr=f1_calldescr)
         guard_false(i3, descr=fdescr2) [i3]
         '''
         bridge = self.attach_bridge(ops, loop, -2)
diff --git a/rpython/jit/backend/llsupport/test/test_runner.py b/rpython/jit/backend/llsupport/test/test_runner.py
--- a/rpython/jit/backend/llsupport/test/test_runner.py
+++ b/rpython/jit/backend/llsupport/test/test_runner.py
@@ -14,7 +14,7 @@
         def set_debug(flag):
             pass
     
-    def compile_loop(self, inputargs, operations, looptoken):
+    def compile_loop(self, logger, inputargs, operations, looptoken):
         py.test.skip("llsupport test: cannot compile operations")
 
 
diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py
--- a/rpython/jit/backend/model.py
+++ b/rpython/jit/backend/model.py
@@ -51,7 +51,8 @@
         """
         return False
 
-    def compile_loop(self, inputargs, operations, looptoken, log=True, name=''):
+    def compile_loop(self, logger, inputargs, operations, looptoken,
+                     log=True, name=''):
         """Assemble the given loop.
         Should create and attach a fresh CompiledLoopToken to
         looptoken.compiled_loop_token and stick extra attributes
@@ -67,7 +68,7 @@
         """
         raise NotImplementedError
 
-    def compile_bridge(self, faildescr, inputargs, operations,
+    def compile_bridge(self, logger, faildescr, inputargs, operations,
                        original_loop_token, log=True):
         """Assemble the bridge.
         The FailDescr is the descr of the original guard that failed.
diff --git a/rpython/jit/backend/test/calling_convention_test.py b/rpython/jit/backend/test/calling_convention_test.py
--- a/rpython/jit/backend/test/calling_convention_test.py
+++ b/rpython/jit/backend/test/calling_convention_test.py
@@ -105,7 +105,7 @@
 
             loop = parse(ops, namespace=locals())
             looptoken = JitCellToken()
-            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+            self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
             argvals, expected_result = self._prepare_args(args, floats, ints)
 
             deadframe = self.cpu.execute_token(looptoken, *argvals)
@@ -249,7 +249,7 @@
             called_looptoken = JitCellToken()
             called_looptoken.outermost_jitdriver_sd = FakeJitDriverSD()
             done_descr = called_loop.operations[-1].getdescr()
-            self.cpu.compile_loop(called_loop.inputargs, called_loop.operations, called_looptoken)
+            self.cpu.compile_loop(None, called_loop.inputargs, called_loop.operations, called_looptoken)
 
             argvals, expected_result = self._prepare_args(args, floats, ints)
             deadframe = cpu.execute_token(called_looptoken, *argvals)
@@ -278,7 +278,7 @@
             self.cpu.done_with_this_frame_descr_float = done_descr
             try:
                 othertoken = JitCellToken()
-                self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
+                self.cpu.compile_loop(None, loop.inputargs, loop.operations, othertoken)
 
                 # prepare call to called_loop
                 argvals, _ = self._prepare_args(args, floats, ints)
@@ -424,7 +424,7 @@
 
             loop = parse(ops, namespace=locals())
             looptoken = JitCellToken()
-            self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+            self.cpu.compile_loop(None, loop.inputargs, loop.operations, looptoken)
             argvals, expected_result = self._prepare_args(args, floats, ints)
 
             deadframe = self.cpu.execute_token(looptoken, *argvals)
diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -49,7 +49,7 @@
                                                                 valueboxes,
                                                                 descr)
         looptoken = JitCellToken()
-        self.cpu.compile_loop(inputargs, operations, looptoken)
+        self.cpu.compile_loop(None, inputargs, operations, looptoken)
         args = []
         for box in inputargs:


More information about the pypy-commit mailing list