[pypy-commit] pypy ppc-jit-backend: merge

hager noreply at buildbot.pypy.org
Tue Jan 3 14:42:06 CET 2012


Author: hager <sven.hager at uni-duesseldorf.de>
Branch: ppc-jit-backend
Changeset: r50997:0529ccad7c00
Date: 2012-01-03 14:41 +0100
http://bitbucket.org/pypy/pypy/changeset/0529ccad7c00/

Log:	merge

diff too long, truncating to 10000 out of 53476 lines

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -1,3 +1,4 @@
 b590cf6de4190623aad9aa698694c22e614d67b9 release-1.5
 b48df0bf4e75b81d98f19ce89d4a7dc3e1dab5e5 benchmarked
 d8ac7d23d3ec5f9a0fa1264972f74a010dbfd07f release-1.6
+ff4af8f318821f7f5ca998613a60fca09aa137da release-1.7
diff --git a/lib-python/modified-2.7/ctypes/__init__.py b/lib-python/modified-2.7/ctypes/__init__.py
--- a/lib-python/modified-2.7/ctypes/__init__.py
+++ b/lib-python/modified-2.7/ctypes/__init__.py
@@ -351,7 +351,7 @@
         self._FuncPtr = _FuncPtr
 
         if handle is None:
-            self._handle = _ffi.CDLL(name)
+            self._handle = _ffi.CDLL(name, mode)
         else:
             self._handle = handle
 
diff --git a/lib-python/modified-2.7/ctypes/test/test_callbacks.py b/lib-python/modified-2.7/ctypes/test/test_callbacks.py
--- a/lib-python/modified-2.7/ctypes/test/test_callbacks.py
+++ b/lib-python/modified-2.7/ctypes/test/test_callbacks.py
@@ -1,5 +1,6 @@
 import unittest
 from ctypes import *
+from ctypes.test import xfail
 import _ctypes_test
 
 class Callbacks(unittest.TestCase):
@@ -98,6 +99,7 @@
 ##        self.check_type(c_char_p, "abc")
 ##        self.check_type(c_char_p, "def")
 
+    @xfail
     def test_pyobject(self):
         o = ()
         from sys import getrefcount as grc
diff --git a/lib-python/modified-2.7/ctypes/test/test_libc.py b/lib-python/modified-2.7/ctypes/test/test_libc.py
--- a/lib-python/modified-2.7/ctypes/test/test_libc.py
+++ b/lib-python/modified-2.7/ctypes/test/test_libc.py
@@ -25,7 +25,10 @@
         lib.my_qsort(chars, len(chars)-1, sizeof(c_char), comparefunc(sort))
         self.assertEqual(chars.raw, "   ,,aaaadmmmnpppsss\x00")
 
-    def test_no_more_xfail(self):
+    def SKIPPED_test_no_more_xfail(self):
+        # We decided to not explicitly support the whole ctypes-2.7
+        # and instead go for a case-by-case, demand-driven approach.
+        # So this test is skipped instead of failing.
         import socket
         import ctypes.test
         self.assertTrue(not hasattr(ctypes.test, 'xfail'),
diff --git a/lib_pypy/_collections.py b/lib_pypy/_collections.py
--- a/lib_pypy/_collections.py
+++ b/lib_pypy/_collections.py
@@ -379,12 +379,14 @@
 class defaultdict(dict):
     
     def __init__(self, *args, **kwds):
-        self.default_factory = None
-        if 'default_factory' in kwds:
-            self.default_factory = kwds.pop('default_factory')
-        elif len(args) > 0 and (callable(args[0]) or args[0] is None):
-            self.default_factory = args[0]
+        if len(args) > 0:
+            default_factory = args[0]
             args = args[1:]
+            if not callable(default_factory) and default_factory is not None:
+                raise TypeError("first argument must be callable")
+        else:
+            default_factory = None
+        self.default_factory = default_factory
         super(defaultdict, self).__init__(*args, **kwds)
  
     def __missing__(self, key):
@@ -404,7 +406,7 @@
             recurse.remove(id(self))
 
     def copy(self):
-        return type(self)(self, default_factory=self.default_factory)
+        return type(self)(self.default_factory, self)
     
     def __copy__(self):
         return self.copy()
diff --git a/lib_pypy/_sha.py b/lib_pypy/_sha.py
--- a/lib_pypy/_sha.py
+++ b/lib_pypy/_sha.py
@@ -1,5 +1,5 @@
 #!/usr/bin/env python
-# -*- coding: iso-8859-1
+# -*- coding: iso-8859-1 -*-
 
 # Note that PyPy contains also a built-in module 'sha' which will hide
 # this one if compiled in.
diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -231,6 +231,11 @@
 sqlite.sqlite3_result_text.argtypes = [c_void_p, c_char_p, c_int, c_void_p]
 sqlite.sqlite3_result_text.restype = None
 
+HAS_LOAD_EXTENSION = hasattr(sqlite, "sqlite3_enable_load_extension")
+if HAS_LOAD_EXTENSION:
+    sqlite.sqlite3_enable_load_extension.argtypes = [c_void_p, c_int]
+    sqlite.sqlite3_enable_load_extension.restype = c_int
+
 ##########################################
 # END Wrapped SQLite C API and constants
 ##########################################
@@ -705,6 +710,15 @@
         from sqlite3.dump import _iterdump
         return _iterdump(self)
 
+    if HAS_LOAD_EXTENSION:
+        def enable_load_extension(self, enabled):
+            self._check_thread()
+            self._check_closed()
+
+            rc = sqlite.sqlite3_enable_load_extension(self.db, int(enabled))
+            if rc != SQLITE_OK:
+                raise OperationalError("Error enabling load extension")
+
 DML, DQL, DDL = range(3)
 
 class Cursor(object):
diff --git a/lib_pypy/distributed/socklayer.py b/lib_pypy/distributed/socklayer.py
--- a/lib_pypy/distributed/socklayer.py
+++ b/lib_pypy/distributed/socklayer.py
@@ -2,7 +2,7 @@
 import py
 from socket import socket
 
-XXX needs import adaptation as 'green' is removed from py lib for years 
+raise ImportError("XXX needs import adaptation as 'green' is removed from py lib for years")
 from py.impl.green.msgstruct import decodemessage, message
 from socket import socket, AF_INET, SOCK_STREAM
 import marshal
diff --git a/lib_pypy/itertools.py b/lib_pypy/itertools.py
--- a/lib_pypy/itertools.py
+++ b/lib_pypy/itertools.py
@@ -25,7 +25,7 @@
 
 __all__ = ['chain', 'count', 'cycle', 'dropwhile', 'groupby', 'ifilter',
            'ifilterfalse', 'imap', 'islice', 'izip', 'repeat', 'starmap',
-           'takewhile', 'tee']
+           'takewhile', 'tee', 'compress', 'product']
 
 try: from __pypy__ import builtinify
 except ImportError: builtinify = lambda f: f
diff --git a/lib_pypy/pyrepl/unix_console.py b/lib_pypy/pyrepl/unix_console.py
--- a/lib_pypy/pyrepl/unix_console.py
+++ b/lib_pypy/pyrepl/unix_console.py
@@ -412,7 +412,12 @@
                    e.args[4] == 'unexpected end of data':
                 pass
             else:
-                raise
+                # was: "raise".  But it crashes pyrepl, and by extension the
+                # pypy currently running, in which we are e.g. in the middle
+                # of some debugging session.  Argh.  Instead just print an
+                # error message to stderr and continue running, for now.
+                self.partial_char = ''
+                sys.stderr.write('\n%s: %s\n' % (e.__class__.__name__, e))
         else:
             self.partial_char = ''
             self.event_queue.push(c)
diff --git a/lib_pypy/syslog.py b/lib_pypy/syslog.py
--- a/lib_pypy/syslog.py
+++ b/lib_pypy/syslog.py
@@ -38,9 +38,27 @@
 _setlogmask.argtypes = (c_int,)
 _setlogmask.restype = c_int
 
+_S_log_open = False
+_S_ident_o = None
+
+def _get_argv():
+    try:
+        import sys
+        script = sys.argv[0]
+        if isinstance(script, str):
+            return script[script.rfind('/')+1:] or None
+    except Exception:
+        pass
+    return None
+
 @builtinify
-def openlog(ident, option, facility):
-    _openlog(ident, option, facility)
+def openlog(ident=None, logoption=0, facility=LOG_USER):
+    global _S_ident_o, _S_log_open
+    if ident is None:
+        ident = _get_argv()
+    _S_ident_o = c_char_p(ident)    # keepalive
+    _openlog(_S_ident_o, logoption, facility)
+    _S_log_open = True
 
 @builtinify
 def syslog(arg1, arg2=None):
@@ -48,11 +66,18 @@
         priority, message = arg1, arg2
     else:
         priority, message = LOG_INFO, arg1
+    # if log is not opened, open it now
+    if not _S_log_open:
+        openlog()
     _syslog(priority, "%s", message)
 
 @builtinify
 def closelog():
-    _closelog()
+    global _S_log_open, S_ident_o
+    if _S_log_open:
+        _closelog()
+        _S_log_open = False
+        _S_ident_o = None
 
 @builtinify
 def setlogmask(mask):
diff --git a/py/_code/code.py b/py/_code/code.py
--- a/py/_code/code.py
+++ b/py/_code/code.py
@@ -164,6 +164,7 @@
         #   if something:  # assume this causes a NameError
         #      # _this_ lines and the one
                #        below we don't want from entry.getsource()
+        end = min(end, len(source))
         for i in range(self.lineno, end):
             if source[i].rstrip().endswith(':'):
                 end = i + 1
@@ -307,7 +308,7 @@
                     self._striptext = 'AssertionError: '
         self._excinfo = tup
         self.type, self.value, tb = self._excinfo
-        self.typename = self.type.__name__
+        self.typename = getattr(self.type, "__name__", "???")
         self.traceback = py.code.Traceback(tb)
 
     def __repr__(self):
diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py
--- a/pypy/annotation/binaryop.py
+++ b/pypy/annotation/binaryop.py
@@ -252,7 +252,26 @@
     # unsignedness is considered a rare and contagious disease
 
     def union((int1, int2)):
-        knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
+        if int1.unsigned == int2.unsigned:
+            knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
+        else:
+            t1 = int1.knowntype
+            if t1 is bool:
+                t1 = int
+            t2 = int2.knowntype
+            if t2 is bool:
+                t2 = int
+
+            if t2 is int:
+                if int2.nonneg == False:
+                    raise UnionError, "Merging %s and a possibly negative int is not allowed" % t1
+                knowntype = t1
+            elif t1 is int:
+                if int1.nonneg == False:
+                    raise UnionError, "Merging %s and a possibly negative int is not allowed" % t2
+                knowntype = t2
+            else:
+                raise UnionError, "Merging these types (%s, %s) is not supported" % (t1, t2)
         return SomeInteger(nonneg=int1.nonneg and int2.nonneg,
                            knowntype=knowntype)
 
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -180,7 +180,12 @@
         if name is None:
             name = pyobj.func_name
         if signature is None:
-            signature = cpython_code_signature(pyobj.func_code)
+            if hasattr(pyobj, '_generator_next_method_of_'):
+                from pypy.interpreter.argument import Signature
+                signature = Signature(['entry'])     # haaaaaack
+                defaults = ()
+            else:
+                signature = cpython_code_signature(pyobj.func_code)
         if defaults is None:
             defaults = pyobj.func_defaults
         self.name = name
diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -591,13 +591,11 @@
     immutable = True
     def __init__(self, method):
         self.method = method
-        
-NUMBER = object()
+
 annotation_to_ll_map = [
     (SomeSingleFloat(), lltype.SingleFloat),
     (s_None, lltype.Void),   # also matches SomeImpossibleValue()
     (s_Bool, lltype.Bool),
-    (SomeInteger(knowntype=r_ulonglong), NUMBER),    
     (SomeFloat(), lltype.Float),
     (SomeLongFloat(), lltype.LongFloat),
     (SomeChar(), lltype.Char),
@@ -623,10 +621,11 @@
             return lltype.Ptr(p.PARENTTYPE)
     if isinstance(s_val, SomePtr):
         return s_val.ll_ptrtype
+    if type(s_val) is SomeInteger:
+        return lltype.build_number(None, s_val.knowntype)
+
     for witness, T in annotation_to_ll_map:
         if witness.contains(s_val):
-            if T is NUMBER:
-                return lltype.build_number(None, s_val.knowntype)
             return T
     if info is None:
         info = ''
@@ -635,7 +634,7 @@
     raise ValueError("%sshould return a low-level type,\ngot instead %r" % (
         info, s_val))
 
-ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map if ll is not NUMBER])
+ll_to_annotation_map = dict([(ll, ann) for ann, ll in annotation_to_ll_map])
 
 def lltype_to_annotation(T):
     try:
diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py
--- a/pypy/annotation/specialize.py
+++ b/pypy/annotation/specialize.py
@@ -36,9 +36,7 @@
             newtup = SpaceOperation('newtuple', starargs, argscopy[-1])
             newstartblock.operations.append(newtup)
             newstartblock.closeblock(Link(argscopy, graph.startblock))
-            graph.startblock.isstartblock = False
             graph.startblock = newstartblock
-            newstartblock.isstartblock = True
             argnames = argnames + ['.star%d' % i for i in range(nb_extra_args)]
             graph.signature = Signature(argnames)
             # note that we can mostly ignore defaults: if nb_extra_args > 0, 
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -856,6 +856,46 @@
         py.test.raises(Exception, a.build_types, f, [])
         # if you want to get a r_uint, you have to be explicit about it
 
+    def test_add_different_ints(self):
+        def f(a, b):
+            return a + b
+        a = self.RPythonAnnotator()
+        py.test.raises(Exception, a.build_types, f, [r_uint, int])
+
+    def test_merge_different_ints(self):
+        def f(a, b):
+            if a:
+                c = a
+            else:
+                c = b
+            return c
+        a = self.RPythonAnnotator()
+        py.test.raises(Exception, a.build_types, f, [r_uint, int])
+
+    def test_merge_ruint_zero(self):
+        def f(a):
+            if a:
+                c = a
+            else:
+                c = 0
+            return c
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [r_uint])
+        assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
+
+    def test_merge_ruint_nonneg_signed(self):
+        def f(a, b):
+            if a:
+                c = a
+            else:
+                assert b >= 0
+                c = b
+            return c
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [r_uint, int])
+        assert s == annmodel.SomeInteger(nonneg = True, unsigned = True)
+
+
     def test_prebuilt_long_that_is_not_too_long(self):
         small_constant = 12L
         def f():
@@ -3029,7 +3069,7 @@
             if g(x, y):
                 g(x, r_uint(y))
         a = self.RPythonAnnotator()
-        a.build_types(f, [int, int])
+        py.test.raises(Exception, a.build_types, f, [int, int])
 
     def test_compare_with_zero(self):
         def g():
diff --git a/pypy/bin/checkmodule.py b/pypy/bin/checkmodule.py
--- a/pypy/bin/checkmodule.py
+++ b/pypy/bin/checkmodule.py
@@ -1,43 +1,45 @@
 #! /usr/bin/env python
 """
-Usage:  checkmodule.py [-b backend] <module-name>
+Usage:  checkmodule.py <module-name>
 
-Compiles the PyPy extension module from pypy/module/<module-name>/
-into a fake program which does nothing. Useful for testing whether a
-modules compiles without doing a full translation. Default backend is cli.
-
-WARNING: this is still incomplete: there are chances that the
-compilation fails with strange errors not due to the module. If a
-module is known to compile during a translation but don't pass
-checkmodule.py, please report the bug (or, better, correct it :-).
+Check annotation and rtyping of the PyPy extension module from
+pypy/module/<module-name>/.  Useful for testing whether a
+modules compiles without doing a full translation.
 """
 import autopath
-import sys
+import sys, os
 
 from pypy.objspace.fake.checkmodule import checkmodule
 
 def main(argv):
-    try:
-        assert len(argv) in (2, 4)
-        if len(argv) == 2:
-            backend = 'cli'
-            modname = argv[1]
-            if modname in ('-h', '--help'):
-                print >> sys.stderr, __doc__
-                sys.exit(0)
-            if modname.startswith('-'):
-                print >> sys.stderr, "Bad command line"
-                print >> sys.stderr, __doc__
-                sys.exit(1)
-        else:
-            _, b, backend, modname = argv
-            assert b == '-b'
-    except AssertionError:
+    if len(argv) != 2:
         print >> sys.stderr, __doc__
         sys.exit(2)
+    modname = argv[1]
+    if modname in ('-h', '--help'):
+        print >> sys.stderr, __doc__
+        sys.exit(0)
+    if modname.startswith('-'):
+        print >> sys.stderr, "Bad command line"
+        print >> sys.stderr, __doc__
+        sys.exit(1)
+    if os.path.sep in modname:
+        if os.path.basename(modname) == '':
+            modname = os.path.dirname(modname)
+        if os.path.basename(os.path.dirname(modname)) != 'module':
+            print >> sys.stderr, "Must give '../module/xxx', or just 'xxx'."
+            sys.exit(1)
+        modname = os.path.basename(modname)
+    try:
+        checkmodule(modname)
+    except Exception, e:
+        import traceback, pdb
+        traceback.print_exc()
+        pdb.post_mortem(sys.exc_info()[2])
+        return 1
     else:
-        checkmodule(modname, backend, interactive=True)
-        print 'Module compiled succesfully'
+        print 'Passed.'
+        return 0
 
 if __name__ == '__main__':
-    main(sys.argv)
+    sys.exit(main(sys.argv))
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -252,6 +252,10 @@
                    "use small tuples",
                    default=False),
 
+        BoolOption("withspecialisedtuple",
+                   "use specialised tuples",
+                   default=False),
+
         BoolOption("withrope", "use ropes as the string implementation",
                    default=False,
                    requires=[("objspace.std.withstrslice", False),
@@ -281,6 +285,9 @@
                    "actually create the full list until the resulting "
                    "list is mutated",
                    default=False),
+        BoolOption("withliststrategies",
+                   "enable optimized ways to store lists of primitives ",
+                   default=True),
 
         BoolOption("withtypeversion",
                    "version type objects when changing them",
@@ -362,6 +369,7 @@
         config.objspace.std.suggest(optimized_list_getitem=True)
         config.objspace.std.suggest(getattributeshortcut=True)
         config.objspace.std.suggest(newshortcut=True)
+        config.objspace.std.suggest(withspecialisedtuple=True)
         #if not IS_64_BITS:
         #    config.objspace.std.suggest(withsmalllong=True)
 
diff --git a/pypy/config/test/test_translationoption.py b/pypy/config/test/test_translationoption.py
new file mode 100644
--- /dev/null
+++ b/pypy/config/test/test_translationoption.py
@@ -0,0 +1,10 @@
+import py
+from pypy.config.translationoption import get_combined_translation_config
+from pypy.config.translationoption import set_opt_level
+from pypy.config.config import ConflictConfigError
+
+
+def test_no_gcrootfinder_with_boehm():
+    config = get_combined_translation_config()
+    config.translation.gcrootfinder = "shadowstack"
+    py.test.raises(ConflictConfigError, set_opt_level, config, '0')
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -70,8 +70,8 @@
                      "statistics": [("translation.gctransformer", "framework")],
                      "generation": [("translation.gctransformer", "framework")],
                      "hybrid": [("translation.gctransformer", "framework")],
-                     "boehm": [("translation.gctransformer", "boehm"),
-                               ("translation.continuation", False)],  # breaks
+                     "boehm": [("translation.continuation", False),  # breaks
+                               ("translation.gctransformer", "boehm")],
                      "markcompact": [("translation.gctransformer", "framework")],
                      "minimark": [("translation.gctransformer", "framework")],
                      },
@@ -399,6 +399,10 @@
     # make_sure_not_resized often relies on it, so we always enable them
     config.translation.suggest(list_comprehension_operations=True)
 
+    # finally, make the choice of the gc definitive.  This will fail
+    # if we have specified strange inconsistent settings.
+    config.translation.gc = config.translation.gc
+
 # ----------------------------------------------------------------
 
 def set_platform(config):
diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -496,6 +496,17 @@
     def setup(self):
         super(AppClassCollector, self).setup()
         cls = self.obj
+        #
+        # <hack>
+        for name in dir(cls):
+            if name.startswith('test_'):
+                func = getattr(cls, name, None)
+                code = getattr(func, 'func_code', None)
+                if code and code.co_flags & 32:
+                    raise AssertionError("unsupported: %r is a generator "
+                                         "app-level test method" % (name,))
+        # </hack>
+        #
         space = cls.space
         clsname = cls.__name__
         if self.config.option.runappdirect:
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
@@ -270,7 +270,12 @@
   - *slicing*:
     the slice start must be within bounds. The stop doesn't need to, but it must
     not be smaller than the start.  All negative indexes are disallowed, except for
-    the [:-1] special case.  No step.
+    the [:-1] special case.  No step.  Slice deletion follows the same rules.
+    
+  - *slice assignment*:
+    only supports ``lst[x:y] = sublist``, if ``len(sublist) == y - x``.
+    In other words, slice assignment cannot change the total length of the list,
+    but just replace items.
 
   - *other operators*:
     ``+``, ``+=``, ``in``, ``*``, ``*=``, ``==``, ``!=`` work as expected.
diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py
--- a/pypy/doc/conf.py
+++ b/pypy/doc/conf.py
@@ -45,9 +45,9 @@
 # built documents.
 #
 # The short X.Y version.
-version = '1.6'
+version = '1.7'
 # The full version, including alpha/beta/rc tags.
-release = '1.6'
+release = '1.7'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/pypy/doc/config/objspace.std.withliststrategies.txt b/pypy/doc/config/objspace.std.withliststrategies.txt
new file mode 100644
--- /dev/null
+++ b/pypy/doc/config/objspace.std.withliststrategies.txt
@@ -0,0 +1,2 @@
+Enable list strategies: Use specialized representations for lists of primitive
+objects, such as ints.
diff --git a/pypy/doc/config/objspace.std.withspecialisedtuple.txt b/pypy/doc/config/objspace.std.withspecialisedtuple.txt
new file mode 100644
--- /dev/null
+++ b/pypy/doc/config/objspace.std.withspecialisedtuple.txt
@@ -0,0 +1,3 @@
+Use "specialized tuples", a custom implementation for some common kinds
+of tuples.  Currently limited to tuples of length 2, in three variants:
+(int, int), (float, float), and a generic (object, object).
diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst
--- a/pypy/doc/cpython_differences.rst
+++ b/pypy/doc/cpython_differences.rst
@@ -262,6 +262,26 @@
 documented as such (as e.g. for hasattr()), in most cases PyPy
 lets the exception propagate instead.
 
+Object Identity of Primitive Values, ``is`` and ``id``
+-------------------------------------------------------
+
+Object identity of primitive values works by value equality, not by identity of
+the wrapper. This means that ``x + 1 is x + 1`` is always true, for arbitrary
+integers ``x``. The rule applies for the following types:
+
+ - ``int``
+
+ - ``float``
+
+ - ``long``
+
+ - ``complex``
+
+This change requires some changes to ``id`` as well. ``id`` fulfills the
+following condition: ``x is y <=> id(x) == id(y)``. Therefore ``id`` of the
+above types will return a value that is computed from the argument, and can
+thus be larger than ``sys.maxint`` (i.e. it can be an arbitrary long).
+
 
 Miscellaneous
 -------------
@@ -284,14 +304,14 @@
   never a dictionary as it sometimes is in CPython. Assigning to
   ``__builtins__`` has no effect.
 
-* Do not compare immutable objects with ``is``.  For example on CPython
-  it is true that ``x is 0`` works, i.e. does the same as ``type(x) is
-  int and x == 0``, but it is so by accident.  If you do instead
-  ``x is 1000``, then it stops working, because 1000 is too large and
-  doesn't come from the internal cache.  In PyPy it fails to work in
-  both cases, because we have no need for a cache at all.
+* directly calling the internal magic methods of a few built-in types
+  with invalid arguments may have a slightly different result.  For
+  example, ``[].__add__(None)`` and ``(2).__add__(None)`` both return
+  ``NotImplemented`` on PyPy; on CPython, only the later does, and the
+  former raises ``TypeError``.  (Of course, ``[]+None`` and ``2+None``
+  both raise ``TypeError`` everywhere.)  This difference is an
+  implementation detail that shows up because of internal C-level slots
+  that PyPy does not have.
 
-* Also, object identity of immutable keys in dictionaries is not necessarily
-  preserved.
 
 .. include:: _ref.txt
diff --git a/pypy/doc/faq.rst b/pypy/doc/faq.rst
--- a/pypy/doc/faq.rst
+++ b/pypy/doc/faq.rst
@@ -112,10 +112,32 @@
 You might be interested in our `benchmarking site`_ and our 
 `jit documentation`_.
 
+Note that the JIT has a very high warm-up cost, meaning that the
+programs are slow at the beginning.  If you want to compare the timings
+with CPython, even relatively simple programs need to run *at least* one
+second, preferrably at least a few seconds.  Large, complicated programs
+need even more time to warm-up the JIT.
+
 .. _`benchmarking site`: http://speed.pypy.org
 
 .. _`jit documentation`: jit/index.html
 
+---------------------------------------------------------------
+Couldn't the JIT dump and reload already-compiled machine code?
+---------------------------------------------------------------
+
+No, we found no way of doing that.  The JIT generates machine code
+containing a large number of constant addresses --- constant at the time
+the machine code is written.  The vast majority is probably not at all
+constants that you find in the executable, with a nice link name.  E.g.
+the addresses of Python classes are used all the time, but Python
+classes don't come statically from the executable; they are created anew
+every time you restart your program.  This makes saving and reloading
+machine code completely impossible without some very advanced way of
+mapping addresses in the old (now-dead) process to addresses in the new
+process, including checking that all the previous assumptions about the
+(now-dead) object are still true about the new object.
+
 
 .. _`prolog and javascript`:
 
diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst
--- a/pypy/doc/how-to-release.rst
+++ b/pypy/doc/how-to-release.rst
@@ -1,6 +1,3 @@
-.. include:: needswork.txt
-
-.. needs work, it talks about svn. also, it is not really user documentation
 
 Making a PyPy Release
 =======================
@@ -12,11 +9,8 @@
 forgetting things. A set of todo files may also work.
 
 Check and prioritize all issues for the release, postpone some if necessary,
-create new  issues also as necessary. A meeting (or meetings) should be
-organized to decide what things are priorities, should go in and work for
-the release. 
-
-An important thing is to get the documentation into an up-to-date state!
+create new  issues also as necessary. An important thing is to get
+the documentation into an up-to-date state!
 
 Release Steps
 ----------------
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -15,7 +15,7 @@
 
 * `FAQ`_: some frequently asked questions.
 
-* `Release 1.6`_: the latest official release
+* `Release 1.7`_: the latest official release
 
 * `PyPy Blog`_: news and status info about PyPy 
 
@@ -75,7 +75,7 @@
 .. _`Getting Started`: getting-started.html
 .. _`Papers`: extradoc.html
 .. _`Videos`: video-index.html
-.. _`Release 1.6`: http://pypy.org/download.html
+.. _`Release 1.7`: http://pypy.org/download.html
 .. _`speed.pypy.org`: http://speed.pypy.org
 .. _`RPython toolchain`: translation.html
 .. _`potential project ideas`: project-ideas.html
@@ -120,9 +120,9 @@
 Windows, on top of .NET, and on top of Java.
 To dig into PyPy it is recommended to try out the current
 Mercurial default branch, which is always working or mostly working,
-instead of the latest release, which is `1.6`__.
+instead of the latest release, which is `1.7`__.
 
-.. __: release-1.6.0.html
+.. __: release-1.7.0.html
 
 PyPy is mainly developed on Linux and Mac OS X.  Windows is supported,
 but platform-specific bugs tend to take longer before we notice and fix
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -23,17 +23,20 @@
 PyPy's implementation of the Python ``long`` type is slower than CPython's.
 Find out why and optimize them.
 
+Make bytearray type fast
+------------------------
+
+PyPy's bytearray type is very inefficient. It would be an interesting
+task to look into possible optimizations on this.
+
 Numpy improvements
 ------------------
 
-This is more of a project-container than a single project. Possible ideas:
+The numpy is rapidly progressing in pypy, so feel free to come to IRC and
+ask for proposed topic. A not necesarilly up-to-date `list of topics`_
+is also available.
 
-* experiment with auto-vectorization using SSE or implement vectorization
-  without automatically detecting it for array operations.
-
-* improve numpy, for example implement memory views.
-
-* interface with fortran/C libraries.
+.. _`list of topics`: https://bitbucket.org/pypy/extradoc/src/extradoc/planning/micronumpy.txt
 
 Improving the jitviewer
 ------------------------
diff --git a/pypy/doc/release-1.7.0.rst b/pypy/doc/release-1.7.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-1.7.0.rst
@@ -0,0 +1,94 @@
+==================================
+PyPy 1.7 - widening the sweet spot
+==================================
+
+We're pleased to announce the 1.7 release of PyPy. As became a habit, this
+release brings a lot of bugfixes and performance improvements over the 1.6
+release. However, unlike the previous releases, the focus has been on widening
+the "sweet spot" of PyPy. That is, classes of Python code that PyPy can greatly
+speed up should be vastly improved with this release. You can download the 1.7
+release here:
+
+    http://pypy.org/download.html
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy 1.7 and cpython 2.7.1`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+This release supports x86 machines running Linux 32/64, Mac OS X 32/64 or
+Windows 32. Windows 64 work is ongoing, but not yet natively supported.
+
+The main topic of this release is widening the range of code which PyPy
+can greatly speed up. On average on
+our benchmark suite, PyPy 1.7 is around **30%** faster than PyPy 1.6 and up
+to **20 times** faster on some benchmarks.
+
+.. _`pypy 1.7 and cpython 2.7.1`: http://speed.pypy.org
+
+
+Highlights
+==========
+
+* Numerous performance improvements. There are too many examples which python
+  constructs now should behave faster to list them.
+
+* Bugfixes and compatibility fixes with CPython.
+
+* Windows fixes.
+
+* PyPy now comes with stackless features enabled by default. However,
+  any loop using stackless features will interrupt the JIT for now, so no real
+  performance improvement for stackless-based programs. Contact pypy-dev for
+  info how to help on removing this restriction.
+
+* NumPy effort in PyPy was renamed numpypy. In order to try using it, simply
+  write::
+
+    import numpypy as numpy
+
+  at the beginning of your program. There is a huge progress on numpy in PyPy
+  since 1.6, the main feature being implementation of dtypes.
+
+* JSON encoder (but not decoder) has been replaced with a new one. This one
+  is written in pure Python, but is known to outperform CPython's C extension
+  up to **2 times** in some cases. It's about **20 times** faster than
+  the one that we had in 1.6.
+
+* The memory footprint of some of our RPython modules has been drastically
+  improved. This should impact any applications using for example cryptography,
+  like tornado.
+
+* There was some progress in exposing even more CPython C API via cpyext.
+
+Things that didn't make it, expect in 1.8 soon
+==============================================
+
+There is an ongoing work, which while didn't make it to the release, is
+probably worth mentioning here. This is what you should probably expect in
+1.8 some time soon:
+
+* Specialized list implementation. There is a branch that implements lists of
+  integers/floats/strings as compactly as array.array. This should drastically
+  improve performance/memory impact of some applications
+
+* NumPy effort is progressing forward, with multi-dimensional arrays coming
+  soon.
+
+* There are two brand new JIT assembler backends, notably for the PowerPC and
+  ARM processors.
+
+Fundraising
+===========
+
+It's maybe worth mentioning that we're running fundraising campaigns for
+NumPy effort in PyPy and for Python 3 in PyPy. In case you want to see any
+of those happen faster, we urge you to donate to `numpy proposal`_ or
+`py3k proposal`_. In case you want PyPy to progress, but you trust us with
+the general direction, you can always donate to the `general pot`_.
+
+.. _`numpy proposal`: http://pypy.org/numpydonate.html
+.. _`py3k proposal`: http://pypy.org/py3donate.html
+.. _`general pot`: http://pypy.org
diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -51,6 +51,24 @@
             space.setattr(self, w_name,
                           space.getitem(w_state, w_name))
 
+    def missing_field(self, space, required, host):
+        "Find which required field is missing."
+        state = self.initialization_state
+        for i in range(len(required)):
+            if (state >> i) & 1:
+                continue  # field is present
+            missing = required[i]
+            if missing is None:
+                continue  # field is optional
+            w_obj = self.getdictvalue(space, missing)
+            if w_obj is None:
+                err = "required field \"%s\" missing from %s"
+                raise operationerrfmt(space.w_TypeError, err, missing, host)
+            else:
+                err = "incorrect type for field \"%s\" in %s"
+                raise operationerrfmt(space.w_TypeError, err, missing, host)
+        raise AssertionError("should not reach here")
+
 
 class NodeVisitorNotImplemented(Exception):
     pass
@@ -94,17 +112,6 @@
 )
 
 
-def missing_field(space, state, required, host):
-    "Find which required field is missing."
-    for i in range(len(required)):
-        if not (state >> i) & 1:
-            missing = required[i]
-            if missing is not None:
-                 err = "required field \"%s\" missing from %s"
-                 err = err % (missing, host)
-                 w_err = space.wrap(err)
-                 raise OperationError(space.w_TypeError, w_err)
-    raise AssertionError("should not reach here")
 
 
 class mod(AST):
@@ -112,7 +119,6 @@
 
 class Module(mod):
 
-
     def __init__(self, body):
         self.body = body
         self.w_body = None
@@ -128,7 +134,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 1:
-            missing_field(space, self.initialization_state, ['body'], 'Module')
+            self.missing_field(space, ['body'], 'Module')
         else:
             pass
         w_list = self.w_body
@@ -145,7 +151,6 @@
 
 class Interactive(mod):
 
-
     def __init__(self, body):
         self.body = body
         self.w_body = None
@@ -161,7 +166,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 1:
-            missing_field(space, self.initialization_state, ['body'], 'Interactive')
+            self.missing_field(space, ['body'], 'Interactive')
         else:
             pass
         w_list = self.w_body
@@ -178,7 +183,6 @@
 
 class Expression(mod):
 
-
     def __init__(self, body):
         self.body = body
         self.initialization_state = 1
@@ -192,7 +196,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 1:
-            missing_field(space, self.initialization_state, ['body'], 'Expression')
+            self.missing_field(space, ['body'], 'Expression')
         else:
             pass
         self.body.sync_app_attrs(space)
@@ -200,7 +204,6 @@
 
 class Suite(mod):
 
-
     def __init__(self, body):
         self.body = body
         self.w_body = None
@@ -216,7 +219,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 1:
-            missing_field(space, self.initialization_state, ['body'], 'Suite')
+            self.missing_field(space, ['body'], 'Suite')
         else:
             pass
         w_list = self.w_body
@@ -232,15 +235,13 @@
 
 
 class stmt(AST):
+
     def __init__(self, lineno, col_offset):
         self.lineno = lineno
         self.col_offset = col_offset
 
 class FunctionDef(stmt):
 
-    _lineno_mask = 16
-    _col_offset_mask = 32
-
     def __init__(self, name, args, body, decorator_list, lineno, col_offset):
         self.name = name
         self.args = args
@@ -264,7 +265,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 63:
-            missing_field(space, self.initialization_state, ['name', 'args', 'body', 'decorator_list', 'lineno', 'col_offset'], 'FunctionDef')
+            self.missing_field(space, ['lineno', 'col_offset', 'name', 'args', 'body', 'decorator_list'], 'FunctionDef')
         else:
             pass
         self.args.sync_app_attrs(space)
@@ -292,9 +293,6 @@
 
 class ClassDef(stmt):
 
-    _lineno_mask = 16
-    _col_offset_mask = 32
-
     def __init__(self, name, bases, body, decorator_list, lineno, col_offset):
         self.name = name
         self.bases = bases
@@ -320,7 +318,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 63:
-            missing_field(space, self.initialization_state, ['name', 'bases', 'body', 'decorator_list', 'lineno', 'col_offset'], 'ClassDef')
+            self.missing_field(space, ['lineno', 'col_offset', 'name', 'bases', 'body', 'decorator_list'], 'ClassDef')
         else:
             pass
         w_list = self.w_bases
@@ -357,9 +355,6 @@
 
 class Return(stmt):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, value, lineno, col_offset):
         self.value = value
         stmt.__init__(self, lineno, col_offset)
@@ -374,10 +369,10 @@
         return visitor.visit_Return(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~1) ^ 6:
-            missing_field(space, self.initialization_state, [None, 'lineno', 'col_offset'], 'Return')
+        if (self.initialization_state & ~4) ^ 3:
+            self.missing_field(space, ['lineno', 'col_offset', None], 'Return')
         else:
-            if not self.initialization_state & 1:
+            if not self.initialization_state & 4:
                 self.value = None
         if self.value:
             self.value.sync_app_attrs(space)
@@ -385,9 +380,6 @@
 
 class Delete(stmt):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, targets, lineno, col_offset):
         self.targets = targets
         self.w_targets = None
@@ -404,7 +396,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['targets', 'lineno', 'col_offset'], 'Delete')
+            self.missing_field(space, ['lineno', 'col_offset', 'targets'], 'Delete')
         else:
             pass
         w_list = self.w_targets
@@ -421,9 +413,6 @@
 
 class Assign(stmt):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, targets, value, lineno, col_offset):
         self.targets = targets
         self.w_targets = None
@@ -442,7 +431,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['targets', 'value', 'lineno', 'col_offset'], 'Assign')
+            self.missing_field(space, ['lineno', 'col_offset', 'targets', 'value'], 'Assign')
         else:
             pass
         w_list = self.w_targets
@@ -460,9 +449,6 @@
 
 class AugAssign(stmt):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, target, op, value, lineno, col_offset):
         self.target = target
         self.op = op
@@ -480,7 +466,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['target', 'op', 'value', 'lineno', 'col_offset'], 'AugAssign')
+            self.missing_field(space, ['lineno', 'col_offset', 'target', 'op', 'value'], 'AugAssign')
         else:
             pass
         self.target.sync_app_attrs(space)
@@ -489,9 +475,6 @@
 
 class Print(stmt):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, dest, values, nl, lineno, col_offset):
         self.dest = dest
         self.values = values
@@ -511,10 +494,10 @@
         return visitor.visit_Print(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~1) ^ 30:
-            missing_field(space, self.initialization_state, [None, 'values', 'nl', 'lineno', 'col_offset'], 'Print')
+        if (self.initialization_state & ~4) ^ 27:
+            self.missing_field(space, ['lineno', 'col_offset', None, 'values', 'nl'], 'Print')
         else:
-            if not self.initialization_state & 1:
+            if not self.initialization_state & 4:
                 self.dest = None
         if self.dest:
             self.dest.sync_app_attrs(space)
@@ -532,9 +515,6 @@
 
 class For(stmt):
 
-    _lineno_mask = 16
-    _col_offset_mask = 32
-
     def __init__(self, target, iter, body, orelse, lineno, col_offset):
         self.target = target
         self.iter = iter
@@ -559,7 +539,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 63:
-            missing_field(space, self.initialization_state, ['target', 'iter', 'body', 'orelse', 'lineno', 'col_offset'], 'For')
+            self.missing_field(space, ['lineno', 'col_offset', 'target', 'iter', 'body', 'orelse'], 'For')
         else:
             pass
         self.target.sync_app_attrs(space)
@@ -588,9 +568,6 @@
 
 class While(stmt):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, test, body, orelse, lineno, col_offset):
         self.test = test
         self.body = body
@@ -613,7 +590,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['test', 'body', 'orelse', 'lineno', 'col_offset'], 'While')
+            self.missing_field(space, ['lineno', 'col_offset', 'test', 'body', 'orelse'], 'While')
         else:
             pass
         self.test.sync_app_attrs(space)
@@ -641,9 +618,6 @@
 
 class If(stmt):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, test, body, orelse, lineno, col_offset):
         self.test = test
         self.body = body
@@ -666,7 +640,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['test', 'body', 'orelse', 'lineno', 'col_offset'], 'If')
+            self.missing_field(space, ['lineno', 'col_offset', 'test', 'body', 'orelse'], 'If')
         else:
             pass
         self.test.sync_app_attrs(space)
@@ -694,9 +668,6 @@
 
 class With(stmt):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, context_expr, optional_vars, body, lineno, col_offset):
         self.context_expr = context_expr
         self.optional_vars = optional_vars
@@ -717,10 +688,10 @@
         return visitor.visit_With(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~2) ^ 29:
-            missing_field(space, self.initialization_state, ['context_expr', None, 'body', 'lineno', 'col_offset'], 'With')
+        if (self.initialization_state & ~8) ^ 23:
+            self.missing_field(space, ['lineno', 'col_offset', 'context_expr', None, 'body'], 'With')
         else:
-            if not self.initialization_state & 2:
+            if not self.initialization_state & 8:
                 self.optional_vars = None
         self.context_expr.sync_app_attrs(space)
         if self.optional_vars:
@@ -739,9 +710,6 @@
 
 class Raise(stmt):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, type, inst, tback, lineno, col_offset):
         self.type = type
         self.inst = inst
@@ -762,14 +730,14 @@
         return visitor.visit_Raise(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~7) ^ 24:
-            missing_field(space, self.initialization_state, [None, None, None, 'lineno', 'col_offset'], 'Raise')
+        if (self.initialization_state & ~28) ^ 3:
+            self.missing_field(space, ['lineno', 'col_offset', None, None, None], 'Raise')
         else:
-            if not self.initialization_state & 1:
+            if not self.initialization_state & 4:
                 self.type = None
-            if not self.initialization_state & 2:
+            if not self.initialization_state & 8:
                 self.inst = None
-            if not self.initialization_state & 4:
+            if not self.initialization_state & 16:
                 self.tback = None
         if self.type:
             self.type.sync_app_attrs(space)
@@ -781,9 +749,6 @@
 
 class TryExcept(stmt):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, body, handlers, orelse, lineno, col_offset):
         self.body = body
         self.w_body = None
@@ -808,7 +773,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['body', 'handlers', 'orelse', 'lineno', 'col_offset'], 'TryExcept')
+            self.missing_field(space, ['lineno', 'col_offset', 'body', 'handlers', 'orelse'], 'TryExcept')
         else:
             pass
         w_list = self.w_body
@@ -845,9 +810,6 @@
 
 class TryFinally(stmt):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, body, finalbody, lineno, col_offset):
         self.body = body
         self.w_body = None
@@ -868,7 +830,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['body', 'finalbody', 'lineno', 'col_offset'], 'TryFinally')
+            self.missing_field(space, ['lineno', 'col_offset', 'body', 'finalbody'], 'TryFinally')
         else:
             pass
         w_list = self.w_body
@@ -895,9 +857,6 @@
 
 class Assert(stmt):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, test, msg, lineno, col_offset):
         self.test = test
         self.msg = msg
@@ -914,10 +873,10 @@
         return visitor.visit_Assert(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~2) ^ 13:
-            missing_field(space, self.initialization_state, ['test', None, 'lineno', 'col_offset'], 'Assert')
+        if (self.initialization_state & ~8) ^ 7:
+            self.missing_field(space, ['lineno', 'col_offset', 'test', None], 'Assert')
         else:
-            if not self.initialization_state & 2:
+            if not self.initialization_state & 8:
                 self.msg = None
         self.test.sync_app_attrs(space)
         if self.msg:
@@ -926,9 +885,6 @@
 
 class Import(stmt):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, names, lineno, col_offset):
         self.names = names
         self.w_names = None
@@ -945,7 +901,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['names', 'lineno', 'col_offset'], 'Import')
+            self.missing_field(space, ['lineno', 'col_offset', 'names'], 'Import')
         else:
             pass
         w_list = self.w_names
@@ -962,9 +918,6 @@
 
 class ImportFrom(stmt):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, module, names, level, lineno, col_offset):
         self.module = module
         self.names = names
@@ -982,12 +935,12 @@
         return visitor.visit_ImportFrom(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~5) ^ 26:
-            missing_field(space, self.initialization_state, [None, 'names', None, 'lineno', 'col_offset'], 'ImportFrom')
+        if (self.initialization_state & ~20) ^ 11:
+            self.missing_field(space, ['lineno', 'col_offset', None, 'names', None], 'ImportFrom')
         else:
-            if not self.initialization_state & 1:
+            if not self.initialization_state & 4:
                 self.module = None
-            if not self.initialization_state & 4:
+            if not self.initialization_state & 16:
                 self.level = 0
         w_list = self.w_names
         if w_list is not None:
@@ -1003,9 +956,6 @@
 
 class Exec(stmt):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, body, globals, locals, lineno, col_offset):
         self.body = body
         self.globals = globals
@@ -1025,12 +975,12 @@
         return visitor.visit_Exec(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~6) ^ 25:
-            missing_field(space, self.initialization_state, ['body', None, None, 'lineno', 'col_offset'], 'Exec')
+        if (self.initialization_state & ~24) ^ 7:
+            self.missing_field(space, ['lineno', 'col_offset', 'body', None, None], 'Exec')
         else:
-            if not self.initialization_state & 2:
+            if not self.initialization_state & 8:
                 self.globals = None
-            if not self.initialization_state & 4:
+            if not self.initialization_state & 16:
                 self.locals = None
         self.body.sync_app_attrs(space)
         if self.globals:
@@ -1041,9 +991,6 @@
 
 class Global(stmt):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, names, lineno, col_offset):
         self.names = names
         self.w_names = None
@@ -1058,7 +1005,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['names', 'lineno', 'col_offset'], 'Global')
+            self.missing_field(space, ['lineno', 'col_offset', 'names'], 'Global')
         else:
             pass
         w_list = self.w_names
@@ -1072,9 +1019,6 @@
 
 class Expr(stmt):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, value, lineno, col_offset):
         self.value = value
         stmt.__init__(self, lineno, col_offset)
@@ -1089,7 +1033,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['value', 'lineno', 'col_offset'], 'Expr')
+            self.missing_field(space, ['lineno', 'col_offset', 'value'], 'Expr')
         else:
             pass
         self.value.sync_app_attrs(space)
@@ -1097,9 +1041,6 @@
 
 class Pass(stmt):
 
-    _lineno_mask = 1
-    _col_offset_mask = 2
-
     def __init__(self, lineno, col_offset):
         stmt.__init__(self, lineno, col_offset)
         self.initialization_state = 3
@@ -1112,16 +1053,13 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 3:
-            missing_field(space, self.initialization_state, ['lineno', 'col_offset'], 'Pass')
+            self.missing_field(space, ['lineno', 'col_offset'], 'Pass')
         else:
             pass
 
 
 class Break(stmt):
 
-    _lineno_mask = 1
-    _col_offset_mask = 2
-
     def __init__(self, lineno, col_offset):
         stmt.__init__(self, lineno, col_offset)
         self.initialization_state = 3
@@ -1134,16 +1072,13 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 3:
-            missing_field(space, self.initialization_state, ['lineno', 'col_offset'], 'Break')
+            self.missing_field(space, ['lineno', 'col_offset'], 'Break')
         else:
             pass
 
 
 class Continue(stmt):
 
-    _lineno_mask = 1
-    _col_offset_mask = 2
-
     def __init__(self, lineno, col_offset):
         stmt.__init__(self, lineno, col_offset)
         self.initialization_state = 3
@@ -1156,21 +1091,19 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 3:
-            missing_field(space, self.initialization_state, ['lineno', 'col_offset'], 'Continue')
+            self.missing_field(space, ['lineno', 'col_offset'], 'Continue')
         else:
             pass
 
 
 class expr(AST):
+
     def __init__(self, lineno, col_offset):
         self.lineno = lineno
         self.col_offset = col_offset
 
 class BoolOp(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, op, values, lineno, col_offset):
         self.op = op
         self.values = values
@@ -1188,7 +1121,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['op', 'values', 'lineno', 'col_offset'], 'BoolOp')
+            self.missing_field(space, ['lineno', 'col_offset', 'op', 'values'], 'BoolOp')
         else:
             pass
         w_list = self.w_values
@@ -1205,9 +1138,6 @@
 
 class BinOp(expr):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, left, op, right, lineno, col_offset):
         self.left = left
         self.op = op
@@ -1225,7 +1155,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['left', 'op', 'right', 'lineno', 'col_offset'], 'BinOp')
+            self.missing_field(space, ['lineno', 'col_offset', 'left', 'op', 'right'], 'BinOp')
         else:
             pass
         self.left.sync_app_attrs(space)
@@ -1234,9 +1164,6 @@
 
 class UnaryOp(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, op, operand, lineno, col_offset):
         self.op = op
         self.operand = operand
@@ -1252,7 +1179,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['op', 'operand', 'lineno', 'col_offset'], 'UnaryOp')
+            self.missing_field(space, ['lineno', 'col_offset', 'op', 'operand'], 'UnaryOp')
         else:
             pass
         self.operand.sync_app_attrs(space)
@@ -1260,9 +1187,6 @@
 
 class Lambda(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, args, body, lineno, col_offset):
         self.args = args
         self.body = body
@@ -1279,7 +1203,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['args', 'body', 'lineno', 'col_offset'], 'Lambda')
+            self.missing_field(space, ['lineno', 'col_offset', 'args', 'body'], 'Lambda')
         else:
             pass
         self.args.sync_app_attrs(space)
@@ -1288,9 +1212,6 @@
 
 class IfExp(expr):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, test, body, orelse, lineno, col_offset):
         self.test = test
         self.body = body
@@ -1309,7 +1230,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['test', 'body', 'orelse', 'lineno', 'col_offset'], 'IfExp')
+            self.missing_field(space, ['lineno', 'col_offset', 'test', 'body', 'orelse'], 'IfExp')
         else:
             pass
         self.test.sync_app_attrs(space)
@@ -1319,9 +1240,6 @@
 
 class Dict(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, keys, values, lineno, col_offset):
         self.keys = keys
         self.w_keys = None
@@ -1342,7 +1260,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['keys', 'values', 'lineno', 'col_offset'], 'Dict')
+            self.missing_field(space, ['lineno', 'col_offset', 'keys', 'values'], 'Dict')
         else:
             pass
         w_list = self.w_keys
@@ -1369,9 +1287,6 @@
 
 class Set(expr):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, elts, lineno, col_offset):
         self.elts = elts
         self.w_elts = None
@@ -1388,7 +1303,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['elts', 'lineno', 'col_offset'], 'Set')
+            self.missing_field(space, ['lineno', 'col_offset', 'elts'], 'Set')
         else:
             pass
         w_list = self.w_elts
@@ -1405,9 +1320,6 @@
 
 class ListComp(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, elt, generators, lineno, col_offset):
         self.elt = elt
         self.generators = generators
@@ -1426,7 +1338,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['elt', 'generators', 'lineno', 'col_offset'], 'ListComp')
+            self.missing_field(space, ['lineno', 'col_offset', 'elt', 'generators'], 'ListComp')
         else:
             pass
         self.elt.sync_app_attrs(space)
@@ -1444,9 +1356,6 @@
 
 class SetComp(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, elt, generators, lineno, col_offset):
         self.elt = elt
         self.generators = generators
@@ -1465,7 +1374,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['elt', 'generators', 'lineno', 'col_offset'], 'SetComp')
+            self.missing_field(space, ['lineno', 'col_offset', 'elt', 'generators'], 'SetComp')
         else:
             pass
         self.elt.sync_app_attrs(space)
@@ -1483,9 +1392,6 @@
 
 class DictComp(expr):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, key, value, generators, lineno, col_offset):
         self.key = key
         self.value = value
@@ -1506,7 +1412,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['key', 'value', 'generators', 'lineno', 'col_offset'], 'DictComp')
+            self.missing_field(space, ['lineno', 'col_offset', 'key', 'value', 'generators'], 'DictComp')
         else:
             pass
         self.key.sync_app_attrs(space)
@@ -1525,9 +1431,6 @@
 
 class GeneratorExp(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, elt, generators, lineno, col_offset):
         self.elt = elt
         self.generators = generators
@@ -1546,7 +1449,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['elt', 'generators', 'lineno', 'col_offset'], 'GeneratorExp')
+            self.missing_field(space, ['lineno', 'col_offset', 'elt', 'generators'], 'GeneratorExp')
         else:
             pass
         self.elt.sync_app_attrs(space)
@@ -1564,9 +1467,6 @@
 
 class Yield(expr):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, value, lineno, col_offset):
         self.value = value
         expr.__init__(self, lineno, col_offset)
@@ -1581,10 +1481,10 @@
         return visitor.visit_Yield(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~1) ^ 6:
-            missing_field(space, self.initialization_state, [None, 'lineno', 'col_offset'], 'Yield')
+        if (self.initialization_state & ~4) ^ 3:
+            self.missing_field(space, ['lineno', 'col_offset', None], 'Yield')
         else:
-            if not self.initialization_state & 1:
+            if not self.initialization_state & 4:
                 self.value = None
         if self.value:
             self.value.sync_app_attrs(space)
@@ -1592,9 +1492,6 @@
 
 class Compare(expr):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, left, ops, comparators, lineno, col_offset):
         self.left = left
         self.ops = ops
@@ -1615,7 +1512,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['left', 'ops', 'comparators', 'lineno', 'col_offset'], 'Compare')
+            self.missing_field(space, ['lineno', 'col_offset', 'left', 'ops', 'comparators'], 'Compare')
         else:
             pass
         self.left.sync_app_attrs(space)
@@ -1640,9 +1537,6 @@
 
 class Call(expr):
 
-    _lineno_mask = 32
-    _col_offset_mask = 64
-
     def __init__(self, func, args, keywords, starargs, kwargs, lineno, col_offset):
         self.func = func
         self.args = args
@@ -1670,12 +1564,12 @@
         return visitor.visit_Call(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~24) ^ 103:
-            missing_field(space, self.initialization_state, ['func', 'args', 'keywords', None, None, 'lineno', 'col_offset'], 'Call')
+        if (self.initialization_state & ~96) ^ 31:
+            self.missing_field(space, ['lineno', 'col_offset', 'func', 'args', 'keywords', None, None], 'Call')
         else:
-            if not self.initialization_state & 8:
+            if not self.initialization_state & 32:
                 self.starargs = None
-            if not self.initialization_state & 16:
+            if not self.initialization_state & 64:
                 self.kwargs = None
         self.func.sync_app_attrs(space)
         w_list = self.w_args
@@ -1706,9 +1600,6 @@
 
 class Repr(expr):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, value, lineno, col_offset):
         self.value = value
         expr.__init__(self, lineno, col_offset)
@@ -1723,7 +1614,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['value', 'lineno', 'col_offset'], 'Repr')
+            self.missing_field(space, ['lineno', 'col_offset', 'value'], 'Repr')
         else:
             pass
         self.value.sync_app_attrs(space)
@@ -1731,9 +1622,6 @@
 
 class Num(expr):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, n, lineno, col_offset):
         self.n = n
         expr.__init__(self, lineno, col_offset)
@@ -1747,16 +1635,13 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['n', 'lineno', 'col_offset'], 'Num')
+            self.missing_field(space, ['lineno', 'col_offset', 'n'], 'Num')
         else:
             pass
 
 
 class Str(expr):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, s, lineno, col_offset):
         self.s = s
         expr.__init__(self, lineno, col_offset)
@@ -1770,16 +1655,13 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['s', 'lineno', 'col_offset'], 'Str')
+            self.missing_field(space, ['lineno', 'col_offset', 's'], 'Str')
         else:
             pass
 
 
 class Attribute(expr):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, value, attr, ctx, lineno, col_offset):
         self.value = value
         self.attr = attr
@@ -1796,7 +1678,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['value', 'attr', 'ctx', 'lineno', 'col_offset'], 'Attribute')
+            self.missing_field(space, ['lineno', 'col_offset', 'value', 'attr', 'ctx'], 'Attribute')
         else:
             pass
         self.value.sync_app_attrs(space)
@@ -1804,9 +1686,6 @@
 
 class Subscript(expr):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, value, slice, ctx, lineno, col_offset):
         self.value = value
         self.slice = slice
@@ -1824,7 +1703,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 31:
-            missing_field(space, self.initialization_state, ['value', 'slice', 'ctx', 'lineno', 'col_offset'], 'Subscript')
+            self.missing_field(space, ['lineno', 'col_offset', 'value', 'slice', 'ctx'], 'Subscript')
         else:
             pass
         self.value.sync_app_attrs(space)
@@ -1833,9 +1712,6 @@
 
 class Name(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, id, ctx, lineno, col_offset):
         self.id = id
         self.ctx = ctx
@@ -1850,16 +1726,13 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['id', 'ctx', 'lineno', 'col_offset'], 'Name')
+            self.missing_field(space, ['lineno', 'col_offset', 'id', 'ctx'], 'Name')
         else:
             pass
 
 
 class List(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, elts, ctx, lineno, col_offset):
         self.elts = elts
         self.w_elts = None
@@ -1877,7 +1750,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['elts', 'ctx', 'lineno', 'col_offset'], 'List')
+            self.missing_field(space, ['lineno', 'col_offset', 'elts', 'ctx'], 'List')
         else:
             pass
         w_list = self.w_elts
@@ -1894,9 +1767,6 @@
 
 class Tuple(expr):
 
-    _lineno_mask = 4
-    _col_offset_mask = 8
-
     def __init__(self, elts, ctx, lineno, col_offset):
         self.elts = elts
         self.w_elts = None
@@ -1914,7 +1784,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 15:
-            missing_field(space, self.initialization_state, ['elts', 'ctx', 'lineno', 'col_offset'], 'Tuple')
+            self.missing_field(space, ['lineno', 'col_offset', 'elts', 'ctx'], 'Tuple')
         else:
             pass
         w_list = self.w_elts
@@ -1931,9 +1801,6 @@
 
 class Const(expr):
 
-    _lineno_mask = 2
-    _col_offset_mask = 4
-
     def __init__(self, value, lineno, col_offset):
         self.value = value
         expr.__init__(self, lineno, col_offset)
@@ -1947,7 +1814,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['value', 'lineno', 'col_offset'], 'Const')
+            self.missing_field(space, ['lineno', 'col_offset', 'value'], 'Const')
         else:
             pass
 
@@ -2009,7 +1876,6 @@
 
 class Ellipsis(slice):
 
-
     def __init__(self):
         self.initialization_state = 0
 
@@ -2021,14 +1887,13 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 0:
-            missing_field(space, self.initialization_state, [], 'Ellipsis')
+            self.missing_field(space, [], 'Ellipsis')
         else:
             pass
 
 
 class Slice(slice):
 
-
     def __init__(self, lower, upper, step):
         self.lower = lower
         self.upper = upper
@@ -2049,7 +1914,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~7) ^ 0:
-            missing_field(space, self.initialization_state, [None, None, None], 'Slice')
+            self.missing_field(space, [None, None, None], 'Slice')
         else:
             if not self.initialization_state & 1:
                 self.lower = None
@@ -2067,7 +1932,6 @@
 
 class ExtSlice(slice):
 
-
     def __init__(self, dims):
         self.dims = dims
         self.w_dims = None
@@ -2083,7 +1947,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 1:
-            missing_field(space, self.initialization_state, ['dims'], 'ExtSlice')
+            self.missing_field(space, ['dims'], 'ExtSlice')
         else:
             pass
         w_list = self.w_dims
@@ -2100,7 +1964,6 @@
 
 class Index(slice):
 
-
     def __init__(self, value):
         self.value = value
         self.initialization_state = 1
@@ -2114,7 +1977,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 1:
-            missing_field(space, self.initialization_state, ['value'], 'Index')
+            self.missing_field(space, ['value'], 'Index')
         else:
             pass
         self.value.sync_app_attrs(space)
@@ -2377,7 +2240,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 7:
-            missing_field(space, self.initialization_state, ['target', 'iter', 'ifs'], 'comprehension')
+            self.missing_field(space, ['target', 'iter', 'ifs'], 'comprehension')
         else:
             pass
         self.target.sync_app_attrs(space)
@@ -2394,15 +2257,13 @@
                 node.sync_app_attrs(space)
 
 class excepthandler(AST):
+
     def __init__(self, lineno, col_offset):
         self.lineno = lineno
         self.col_offset = col_offset
 
 class ExceptHandler(excepthandler):
 
-    _lineno_mask = 8
-    _col_offset_mask = 16
-
     def __init__(self, type, name, body, lineno, col_offset):
         self.type = type
         self.name = name
@@ -2424,12 +2285,12 @@
         return visitor.visit_ExceptHandler(self)
 
     def sync_app_attrs(self, space):
-        if (self.initialization_state & ~3) ^ 28:
-            missing_field(space, self.initialization_state, [None, None, 'body', 'lineno', 'col_offset'], 'ExceptHandler')
+        if (self.initialization_state & ~12) ^ 19:
+            self.missing_field(space, ['lineno', 'col_offset', None, None, 'body'], 'ExceptHandler')
         else:
-            if not self.initialization_state & 1:
+            if not self.initialization_state & 4:
                 self.type = None
-            if not self.initialization_state & 2:
+            if not self.initialization_state & 8:
                 self.name = None
         if self.type:
             self.type.sync_app_attrs(space)
@@ -2470,7 +2331,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~6) ^ 9:
-            missing_field(space, self.initialization_state, ['args', None, None, 'defaults'], 'arguments')
+            self.missing_field(space, ['args', None, None, 'defaults'], 'arguments')
         else:
             if not self.initialization_state & 2:
                 self.vararg = None
@@ -2513,7 +2374,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~0) ^ 3:
-            missing_field(space, self.initialization_state, ['arg', 'value'], 'keyword')
+            self.missing_field(space, ['arg', 'value'], 'keyword')
         else:
             pass
         self.value.sync_app_attrs(space)
@@ -2533,7 +2394,7 @@
 
     def sync_app_attrs(self, space):
         if (self.initialization_state & ~2) ^ 1:
-            missing_field(space, self.initialization_state, ['name', None], 'alias')
+            self.missing_field(space, ['name', None], 'alias')
         else:
             if not self.initialization_state & 2:
                 self.asname = None
@@ -3019,6 +2880,8 @@
 def Expression_set_body(space, w_self, w_new_value):
     try:
         w_self.body = space.interp_w(expr, w_new_value, False)
+        if type(w_self.body) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
@@ -3098,7 +2961,7 @@
         w_obj = w_self.getdictvalue(space, 'lineno')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & w_self._lineno_mask:
+    if not w_self.initialization_state & 1:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'lineno')
     return space.wrap(w_self.lineno)
@@ -3112,14 +2975,14 @@
         w_self.setdictvalue(space, 'lineno', w_new_value)
         return
     w_self.deldictvalue(space, 'lineno')
-    w_self.initialization_state |= w_self._lineno_mask
+    w_self.initialization_state |= 1
 
 def stmt_get_col_offset(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'col_offset')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & w_self._col_offset_mask:
+    if not w_self.initialization_state & 2:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'col_offset')
     return space.wrap(w_self.col_offset)
@@ -3133,7 +2996,7 @@
         w_self.setdictvalue(space, 'col_offset', w_new_value)
         return
     w_self.deldictvalue(space, 'col_offset')
-    w_self.initialization_state |= w_self._col_offset_mask
+    w_self.initialization_state |= 2
 
 stmt.typedef = typedef.TypeDef("stmt",
     AST.typedef,
@@ -3149,7 +3012,7 @@
         w_obj = w_self.getdictvalue(space, 'name')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name')
     return space.wrap(w_self.name)
@@ -3163,14 +3026,14 @@
         w_self.setdictvalue(space, 'name', w_new_value)
         return
     w_self.deldictvalue(space, 'name')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def FunctionDef_get_args(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'args')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'args')
     return space.wrap(w_self.args)
@@ -3184,10 +3047,10 @@
         w_self.setdictvalue(space, 'args', w_new_value)
         return
     w_self.deldictvalue(space, 'args')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def FunctionDef_get_body(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     if w_self.w_body is None:
@@ -3201,10 +3064,10 @@
 
 def FunctionDef_set_body(space, w_self, w_new_value):
     w_self.w_body = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 def FunctionDef_get_decorator_list(space, w_self):
-    if not w_self.initialization_state & 8:
+    if not w_self.initialization_state & 32:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'decorator_list')
     if w_self.w_decorator_list is None:
@@ -3218,7 +3081,7 @@
 
 def FunctionDef_set_decorator_list(space, w_self, w_new_value):
     w_self.w_decorator_list = w_new_value
-    w_self.initialization_state |= 8
+    w_self.initialization_state |= 32
 
 _FunctionDef_field_unroller = unrolling_iterable(['name', 'args', 'body', 'decorator_list'])
 def FunctionDef_init(space, w_self, __args__):
@@ -3254,7 +3117,7 @@
         w_obj = w_self.getdictvalue(space, 'name')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name')
     return space.wrap(w_self.name)
@@ -3268,10 +3131,10 @@
         w_self.setdictvalue(space, 'name', w_new_value)
         return
     w_self.deldictvalue(space, 'name')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def ClassDef_get_bases(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'bases')
     if w_self.w_bases is None:
@@ -3285,10 +3148,10 @@
 
 def ClassDef_set_bases(space, w_self, w_new_value):
     w_self.w_bases = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def ClassDef_get_body(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     if w_self.w_body is None:
@@ -3302,10 +3165,10 @@
 
 def ClassDef_set_body(space, w_self, w_new_value):
     w_self.w_body = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 def ClassDef_get_decorator_list(space, w_self):
-    if not w_self.initialization_state & 8:
+    if not w_self.initialization_state & 32:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'decorator_list')
     if w_self.w_decorator_list is None:
@@ -3319,7 +3182,7 @@
 
 def ClassDef_set_decorator_list(space, w_self, w_new_value):
     w_self.w_decorator_list = w_new_value
-    w_self.initialization_state |= 8
+    w_self.initialization_state |= 32
 
 _ClassDef_field_unroller = unrolling_iterable(['name', 'bases', 'body', 'decorator_list'])
 def ClassDef_init(space, w_self, __args__):
@@ -3356,7 +3219,7 @@
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return space.wrap(w_self.value)
@@ -3364,13 +3227,15 @@
 def Return_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, True)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Return_field_unroller = unrolling_iterable(['value'])
 def Return_init(space, w_self, __args__):
@@ -3397,7 +3262,7 @@
 )
 
 def Delete_get_targets(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'targets')
     if w_self.w_targets is None:
@@ -3411,7 +3276,7 @@
 
 def Delete_set_targets(space, w_self, w_new_value):
     w_self.w_targets = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Delete_field_unroller = unrolling_iterable(['targets'])
 def Delete_init(space, w_self, __args__):
@@ -3439,7 +3304,7 @@
 )
 
 def Assign_get_targets(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'targets')
     if w_self.w_targets is None:
@@ -3453,14 +3318,14 @@
 
 def Assign_set_targets(space, w_self, w_new_value):
     w_self.w_targets = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Assign_get_value(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return space.wrap(w_self.value)
@@ -3468,13 +3333,15 @@
 def Assign_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _Assign_field_unroller = unrolling_iterable(['targets', 'value'])
 def Assign_init(space, w_self, __args__):
@@ -3507,7 +3374,7 @@
         w_obj = w_self.getdictvalue(space, 'target')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'target')
     return space.wrap(w_self.target)
@@ -3515,20 +3382,22 @@
 def AugAssign_set_target(space, w_self, w_new_value):
     try:
         w_self.target = space.interp_w(expr, w_new_value, False)
+        if type(w_self.target) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'target', w_new_value)
         return
     w_self.deldictvalue(space, 'target')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def AugAssign_get_op(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'op')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'op')
     return operator_to_class[w_self.op - 1]()
@@ -3544,14 +3413,14 @@
         return
     # need to save the original object too
     w_self.setdictvalue(space, 'op', w_new_value)
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def AugAssign_get_value(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return space.wrap(w_self.value)
@@ -3559,13 +3428,15 @@
 def AugAssign_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _AugAssign_field_unroller = unrolling_iterable(['target', 'op', 'value'])
 def AugAssign_init(space, w_self, __args__):
@@ -3598,7 +3469,7 @@
         w_obj = w_self.getdictvalue(space, 'dest')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'dest')
     return space.wrap(w_self.dest)
@@ -3606,16 +3477,18 @@
 def Print_set_dest(space, w_self, w_new_value):
     try:
         w_self.dest = space.interp_w(expr, w_new_value, True)
+        if type(w_self.dest) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'dest', w_new_value)
         return
     w_self.deldictvalue(space, 'dest')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Print_get_values(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'values')
     if w_self.w_values is None:
@@ -3629,14 +3502,14 @@
 
 def Print_set_values(space, w_self, w_new_value):
     w_self.w_values = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def Print_get_nl(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'nl')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'nl')
     return space.wrap(w_self.nl)
@@ -3650,7 +3523,7 @@
         w_self.setdictvalue(space, 'nl', w_new_value)
         return
     w_self.deldictvalue(space, 'nl')
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _Print_field_unroller = unrolling_iterable(['dest', 'values', 'nl'])
 def Print_init(space, w_self, __args__):
@@ -3684,7 +3557,7 @@
         w_obj = w_self.getdictvalue(space, 'target')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'target')
     return space.wrap(w_self.target)
@@ -3692,20 +3565,22 @@
 def For_set_target(space, w_self, w_new_value):
     try:
         w_self.target = space.interp_w(expr, w_new_value, False)
+        if type(w_self.target) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'target', w_new_value)
         return
     w_self.deldictvalue(space, 'target')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def For_get_iter(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'iter')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'iter')
     return space.wrap(w_self.iter)
@@ -3713,16 +3588,18 @@
 def For_set_iter(space, w_self, w_new_value):
     try:
         w_self.iter = space.interp_w(expr, w_new_value, False)
+        if type(w_self.iter) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'iter', w_new_value)
         return
     w_self.deldictvalue(space, 'iter')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def For_get_body(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     if w_self.w_body is None:
@@ -3736,10 +3613,10 @@
 
 def For_set_body(space, w_self, w_new_value):
     w_self.w_body = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 def For_get_orelse(space, w_self):
-    if not w_self.initialization_state & 8:
+    if not w_self.initialization_state & 32:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
     if w_self.w_orelse is None:
@@ -3753,7 +3630,7 @@
 
 def For_set_orelse(space, w_self, w_new_value):
     w_self.w_orelse = w_new_value
-    w_self.initialization_state |= 8
+    w_self.initialization_state |= 32
 
 _For_field_unroller = unrolling_iterable(['target', 'iter', 'body', 'orelse'])
 def For_init(space, w_self, __args__):
@@ -3789,7 +3666,7 @@
         w_obj = w_self.getdictvalue(space, 'test')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'test')
     return space.wrap(w_self.test)
@@ -3797,16 +3674,18 @@
 def While_set_test(space, w_self, w_new_value):
     try:
         w_self.test = space.interp_w(expr, w_new_value, False)
+        if type(w_self.test) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'test', w_new_value)
         return
     w_self.deldictvalue(space, 'test')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def While_get_body(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     if w_self.w_body is None:
@@ -3820,10 +3699,10 @@
 
 def While_set_body(space, w_self, w_new_value):
     w_self.w_body = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def While_get_orelse(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
     if w_self.w_orelse is None:
@@ -3837,7 +3716,7 @@
 
 def While_set_orelse(space, w_self, w_new_value):
     w_self.w_orelse = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _While_field_unroller = unrolling_iterable(['test', 'body', 'orelse'])
 def While_init(space, w_self, __args__):
@@ -3872,7 +3751,7 @@
         w_obj = w_self.getdictvalue(space, 'test')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'test')
     return space.wrap(w_self.test)
@@ -3880,16 +3759,18 @@
 def If_set_test(space, w_self, w_new_value):
     try:
         w_self.test = space.interp_w(expr, w_new_value, False)
+        if type(w_self.test) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'test', w_new_value)
         return
     w_self.deldictvalue(space, 'test')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def If_get_body(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     if w_self.w_body is None:
@@ -3903,10 +3784,10 @@
 
 def If_set_body(space, w_self, w_new_value):
     w_self.w_body = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def If_get_orelse(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
     if w_self.w_orelse is None:
@@ -3920,7 +3801,7 @@
 
 def If_set_orelse(space, w_self, w_new_value):
     w_self.w_orelse = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _If_field_unroller = unrolling_iterable(['test', 'body', 'orelse'])
 def If_init(space, w_self, __args__):
@@ -3955,7 +3836,7 @@
         w_obj = w_self.getdictvalue(space, 'context_expr')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'context_expr')
     return space.wrap(w_self.context_expr)
@@ -3963,20 +3844,22 @@
 def With_set_context_expr(space, w_self, w_new_value):
     try:
         w_self.context_expr = space.interp_w(expr, w_new_value, False)
+        if type(w_self.context_expr) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'context_expr', w_new_value)
         return
     w_self.deldictvalue(space, 'context_expr')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def With_get_optional_vars(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'optional_vars')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'optional_vars')
     return space.wrap(w_self.optional_vars)
@@ -3984,16 +3867,18 @@
 def With_set_optional_vars(space, w_self, w_new_value):
     try:
         w_self.optional_vars = space.interp_w(expr, w_new_value, True)
+        if type(w_self.optional_vars) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'optional_vars', w_new_value)
         return
     w_self.deldictvalue(space, 'optional_vars')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def With_get_body(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     if w_self.w_body is None:
@@ -4007,7 +3892,7 @@
 
 def With_set_body(space, w_self, w_new_value):
     w_self.w_body = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _With_field_unroller = unrolling_iterable(['context_expr', 'optional_vars', 'body'])
 def With_init(space, w_self, __args__):
@@ -4041,7 +3926,7 @@
         w_obj = w_self.getdictvalue(space, 'type')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'type')
     return space.wrap(w_self.type)
@@ -4049,20 +3934,22 @@
 def Raise_set_type(space, w_self, w_new_value):
     try:
         w_self.type = space.interp_w(expr, w_new_value, True)
+        if type(w_self.type) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'type', w_new_value)
         return
     w_self.deldictvalue(space, 'type')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Raise_get_inst(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'inst')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'inst')
     return space.wrap(w_self.inst)
@@ -4070,20 +3957,22 @@
 def Raise_set_inst(space, w_self, w_new_value):
     try:
         w_self.inst = space.interp_w(expr, w_new_value, True)
+        if type(w_self.inst) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'inst', w_new_value)
         return
     w_self.deldictvalue(space, 'inst')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def Raise_get_tback(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'tback')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'tback')
     return space.wrap(w_self.tback)
@@ -4091,13 +3980,15 @@
 def Raise_set_tback(space, w_self, w_new_value):
     try:
         w_self.tback = space.interp_w(expr, w_new_value, True)
+        if type(w_self.tback) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'tback', w_new_value)
         return
     w_self.deldictvalue(space, 'tback')
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _Raise_field_unroller = unrolling_iterable(['type', 'inst', 'tback'])
 def Raise_init(space, w_self, __args__):
@@ -4126,7 +4017,7 @@
 )
 
 def TryExcept_get_body(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     if w_self.w_body is None:
@@ -4140,10 +4031,10 @@
 
 def TryExcept_set_body(space, w_self, w_new_value):
     w_self.w_body = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def TryExcept_get_handlers(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'handlers')
     if w_self.w_handlers is None:
@@ -4157,10 +4048,10 @@
 
 def TryExcept_set_handlers(space, w_self, w_new_value):
     w_self.w_handlers = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def TryExcept_get_orelse(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
     if w_self.w_orelse is None:
@@ -4174,7 +4065,7 @@
 
 def TryExcept_set_orelse(space, w_self, w_new_value):
     w_self.w_orelse = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _TryExcept_field_unroller = unrolling_iterable(['body', 'handlers', 'orelse'])
 def TryExcept_init(space, w_self, __args__):
@@ -4206,7 +4097,7 @@
 )
 
 def TryFinally_get_body(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     if w_self.w_body is None:
@@ -4220,10 +4111,10 @@
 
 def TryFinally_set_body(space, w_self, w_new_value):
     w_self.w_body = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def TryFinally_get_finalbody(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'finalbody')
     if w_self.w_finalbody is None:
@@ -4237,7 +4128,7 @@
 
 def TryFinally_set_finalbody(space, w_self, w_new_value):
     w_self.w_finalbody = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _TryFinally_field_unroller = unrolling_iterable(['body', 'finalbody'])
 def TryFinally_init(space, w_self, __args__):
@@ -4271,7 +4162,7 @@
         w_obj = w_self.getdictvalue(space, 'test')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'test')
     return space.wrap(w_self.test)
@@ -4279,20 +4170,22 @@
 def Assert_set_test(space, w_self, w_new_value):
     try:
         w_self.test = space.interp_w(expr, w_new_value, False)
+        if type(w_self.test) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'test', w_new_value)
         return
     w_self.deldictvalue(space, 'test')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Assert_get_msg(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'msg')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'msg')
     return space.wrap(w_self.msg)
@@ -4300,13 +4193,15 @@
 def Assert_set_msg(space, w_self, w_new_value):
     try:
         w_self.msg = space.interp_w(expr, w_new_value, True)
+        if type(w_self.msg) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'msg', w_new_value)
         return
     w_self.deldictvalue(space, 'msg')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _Assert_field_unroller = unrolling_iterable(['test', 'msg'])
 def Assert_init(space, w_self, __args__):
@@ -4334,7 +4229,7 @@
 )
 
 def Import_get_names(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'names')
     if w_self.w_names is None:
@@ -4348,7 +4243,7 @@
 
 def Import_set_names(space, w_self, w_new_value):
     w_self.w_names = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Import_field_unroller = unrolling_iterable(['names'])
 def Import_init(space, w_self, __args__):
@@ -4380,7 +4275,7 @@
         w_obj = w_self.getdictvalue(space, 'module')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'module')
     return space.wrap(w_self.module)
@@ -4397,10 +4292,10 @@
         w_self.setdictvalue(space, 'module', w_new_value)
         return
     w_self.deldictvalue(space, 'module')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def ImportFrom_get_names(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'names')
     if w_self.w_names is None:
@@ -4414,14 +4309,14 @@
 
 def ImportFrom_set_names(space, w_self, w_new_value):
     w_self.w_names = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def ImportFrom_get_level(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'level')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'level')
     return space.wrap(w_self.level)
@@ -4435,7 +4330,7 @@
         w_self.setdictvalue(space, 'level', w_new_value)
         return
     w_self.deldictvalue(space, 'level')
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _ImportFrom_field_unroller = unrolling_iterable(['module', 'names', 'level'])
 def ImportFrom_init(space, w_self, __args__):
@@ -4469,7 +4364,7 @@
         w_obj = w_self.getdictvalue(space, 'body')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     return space.wrap(w_self.body)
@@ -4477,20 +4372,22 @@
 def Exec_set_body(space, w_self, w_new_value):
     try:
         w_self.body = space.interp_w(expr, w_new_value, False)
+        if type(w_self.body) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'body', w_new_value)
         return
     w_self.deldictvalue(space, 'body')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Exec_get_globals(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'globals')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'globals')
     return space.wrap(w_self.globals)
@@ -4498,20 +4395,22 @@
 def Exec_set_globals(space, w_self, w_new_value):
     try:
         w_self.globals = space.interp_w(expr, w_new_value, True)
+        if type(w_self.globals) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'globals', w_new_value)
         return
     w_self.deldictvalue(space, 'globals')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def Exec_get_locals(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'locals')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'locals')
     return space.wrap(w_self.locals)
@@ -4519,13 +4418,15 @@
 def Exec_set_locals(space, w_self, w_new_value):
     try:
         w_self.locals = space.interp_w(expr, w_new_value, True)
+        if type(w_self.locals) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'locals', w_new_value)
         return
     w_self.deldictvalue(space, 'locals')
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _Exec_field_unroller = unrolling_iterable(['body', 'globals', 'locals'])
 def Exec_init(space, w_self, __args__):
@@ -4554,7 +4455,7 @@
 )
 
 def Global_get_names(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'names')
     if w_self.w_names is None:
@@ -4568,7 +4469,7 @@
 
 def Global_set_names(space, w_self, w_new_value):
     w_self.w_names = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Global_field_unroller = unrolling_iterable(['names'])
 def Global_init(space, w_self, __args__):
@@ -4600,7 +4501,7 @@
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return space.wrap(w_self.value)
@@ -4608,13 +4509,15 @@
 def Expr_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Expr_field_unroller = unrolling_iterable(['value'])
 def Expr_init(space, w_self, __args__):
@@ -4696,7 +4599,7 @@
         w_obj = w_self.getdictvalue(space, 'lineno')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & w_self._lineno_mask:
+    if not w_self.initialization_state & 1:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'lineno')
     return space.wrap(w_self.lineno)
@@ -4710,14 +4613,14 @@
         w_self.setdictvalue(space, 'lineno', w_new_value)
         return
     w_self.deldictvalue(space, 'lineno')
-    w_self.initialization_state |= w_self._lineno_mask
+    w_self.initialization_state |= 1
 
 def expr_get_col_offset(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'col_offset')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & w_self._col_offset_mask:
+    if not w_self.initialization_state & 2:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'col_offset')
     return space.wrap(w_self.col_offset)
@@ -4731,7 +4634,7 @@
         w_self.setdictvalue(space, 'col_offset', w_new_value)
         return
     w_self.deldictvalue(space, 'col_offset')
-    w_self.initialization_state |= w_self._col_offset_mask
+    w_self.initialization_state |= 2
 
 expr.typedef = typedef.TypeDef("expr",
     AST.typedef,
@@ -4747,7 +4650,7 @@
         w_obj = w_self.getdictvalue(space, 'op')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'op')
     return boolop_to_class[w_self.op - 1]()
@@ -4763,10 +4666,10 @@
         return
     # need to save the original object too
     w_self.setdictvalue(space, 'op', w_new_value)
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def BoolOp_get_values(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'values')
     if w_self.w_values is None:
@@ -4780,7 +4683,7 @@
 
 def BoolOp_set_values(space, w_self, w_new_value):
     w_self.w_values = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _BoolOp_field_unroller = unrolling_iterable(['op', 'values'])
 def BoolOp_init(space, w_self, __args__):
@@ -4813,7 +4716,7 @@
         w_obj = w_self.getdictvalue(space, 'left')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'left')
     return space.wrap(w_self.left)
@@ -4821,20 +4724,22 @@
 def BinOp_set_left(space, w_self, w_new_value):
     try:
         w_self.left = space.interp_w(expr, w_new_value, False)
+        if type(w_self.left) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'left', w_new_value)
         return
     w_self.deldictvalue(space, 'left')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def BinOp_get_op(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'op')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'op')
     return operator_to_class[w_self.op - 1]()
@@ -4850,14 +4755,14 @@
         return
     # need to save the original object too
     w_self.setdictvalue(space, 'op', w_new_value)
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def BinOp_get_right(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'right')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'right')
     return space.wrap(w_self.right)
@@ -4865,13 +4770,15 @@
 def BinOp_set_right(space, w_self, w_new_value):
     try:
         w_self.right = space.interp_w(expr, w_new_value, False)
+        if type(w_self.right) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'right', w_new_value)
         return
     w_self.deldictvalue(space, 'right')
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _BinOp_field_unroller = unrolling_iterable(['left', 'op', 'right'])
 def BinOp_init(space, w_self, __args__):
@@ -4904,7 +4811,7 @@
         w_obj = w_self.getdictvalue(space, 'op')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'op')
     return unaryop_to_class[w_self.op - 1]()
@@ -4920,14 +4827,14 @@
         return
     # need to save the original object too
     w_self.setdictvalue(space, 'op', w_new_value)
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def UnaryOp_get_operand(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'operand')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'operand')
     return space.wrap(w_self.operand)
@@ -4935,13 +4842,15 @@
 def UnaryOp_set_operand(space, w_self, w_new_value):
     try:
         w_self.operand = space.interp_w(expr, w_new_value, False)
+        if type(w_self.operand) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'operand', w_new_value)
         return
     w_self.deldictvalue(space, 'operand')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _UnaryOp_field_unroller = unrolling_iterable(['op', 'operand'])
 def UnaryOp_init(space, w_self, __args__):
@@ -4973,7 +4882,7 @@
         w_obj = w_self.getdictvalue(space, 'args')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'args')
     return space.wrap(w_self.args)
@@ -4987,14 +4896,14 @@
         w_self.setdictvalue(space, 'args', w_new_value)
         return
     w_self.deldictvalue(space, 'args')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Lambda_get_body(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'body')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     return space.wrap(w_self.body)
@@ -5002,13 +4911,15 @@
 def Lambda_set_body(space, w_self, w_new_value):
     try:
         w_self.body = space.interp_w(expr, w_new_value, False)
+        if type(w_self.body) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'body', w_new_value)
         return
     w_self.deldictvalue(space, 'body')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _Lambda_field_unroller = unrolling_iterable(['args', 'body'])
 def Lambda_init(space, w_self, __args__):
@@ -5040,7 +4951,7 @@
         w_obj = w_self.getdictvalue(space, 'test')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'test')
     return space.wrap(w_self.test)
@@ -5048,20 +4959,22 @@
 def IfExp_set_test(space, w_self, w_new_value):
     try:
         w_self.test = space.interp_w(expr, w_new_value, False)
+        if type(w_self.test) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'test', w_new_value)
         return
     w_self.deldictvalue(space, 'test')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def IfExp_get_body(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'body')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     return space.wrap(w_self.body)
@@ -5069,20 +4982,22 @@
 def IfExp_set_body(space, w_self, w_new_value):
     try:
         w_self.body = space.interp_w(expr, w_new_value, False)
+        if type(w_self.body) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'body', w_new_value)
         return
     w_self.deldictvalue(space, 'body')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def IfExp_get_orelse(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'orelse')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'orelse')
     return space.wrap(w_self.orelse)
@@ -5090,13 +5005,15 @@
 def IfExp_set_orelse(space, w_self, w_new_value):
     try:
         w_self.orelse = space.interp_w(expr, w_new_value, False)
+        if type(w_self.orelse) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'orelse', w_new_value)
         return
     w_self.deldictvalue(space, 'orelse')
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _IfExp_field_unroller = unrolling_iterable(['test', 'body', 'orelse'])
 def IfExp_init(space, w_self, __args__):
@@ -5125,7 +5042,7 @@
 )
 
 def Dict_get_keys(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'keys')
     if w_self.w_keys is None:
@@ -5139,10 +5056,10 @@
 
 def Dict_set_keys(space, w_self, w_new_value):
     w_self.w_keys = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Dict_get_values(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'values')
     if w_self.w_values is None:
@@ -5156,7 +5073,7 @@
 
 def Dict_set_values(space, w_self, w_new_value):
     w_self.w_values = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _Dict_field_unroller = unrolling_iterable(['keys', 'values'])
 def Dict_init(space, w_self, __args__):
@@ -5186,7 +5103,7 @@
 )
 
 def Set_get_elts(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elts')
     if w_self.w_elts is None:
@@ -5200,7 +5117,7 @@
 
 def Set_set_elts(space, w_self, w_new_value):
     w_self.w_elts = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Set_field_unroller = unrolling_iterable(['elts'])
 def Set_init(space, w_self, __args__):
@@ -5232,7 +5149,7 @@
         w_obj = w_self.getdictvalue(space, 'elt')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elt')
     return space.wrap(w_self.elt)
@@ -5240,16 +5157,18 @@
 def ListComp_set_elt(space, w_self, w_new_value):
     try:
         w_self.elt = space.interp_w(expr, w_new_value, False)
+        if type(w_self.elt) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'elt', w_new_value)
         return
     w_self.deldictvalue(space, 'elt')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def ListComp_get_generators(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'generators')
     if w_self.w_generators is None:
@@ -5263,7 +5182,7 @@
 
 def ListComp_set_generators(space, w_self, w_new_value):
     w_self.w_generators = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _ListComp_field_unroller = unrolling_iterable(['elt', 'generators'])
 def ListComp_init(space, w_self, __args__):
@@ -5296,7 +5215,7 @@
         w_obj = w_self.getdictvalue(space, 'elt')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elt')
     return space.wrap(w_self.elt)
@@ -5304,16 +5223,18 @@
 def SetComp_set_elt(space, w_self, w_new_value):
     try:
         w_self.elt = space.interp_w(expr, w_new_value, False)
+        if type(w_self.elt) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'elt', w_new_value)
         return
     w_self.deldictvalue(space, 'elt')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def SetComp_get_generators(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'generators')
     if w_self.w_generators is None:
@@ -5327,7 +5248,7 @@
 
 def SetComp_set_generators(space, w_self, w_new_value):
     w_self.w_generators = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _SetComp_field_unroller = unrolling_iterable(['elt', 'generators'])
 def SetComp_init(space, w_self, __args__):
@@ -5360,7 +5281,7 @@
         w_obj = w_self.getdictvalue(space, 'key')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'key')
     return space.wrap(w_self.key)
@@ -5368,20 +5289,22 @@
 def DictComp_set_key(space, w_self, w_new_value):
     try:
         w_self.key = space.interp_w(expr, w_new_value, False)
+        if type(w_self.key) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'key', w_new_value)
         return
     w_self.deldictvalue(space, 'key')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def DictComp_get_value(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return space.wrap(w_self.value)
@@ -5389,16 +5312,18 @@
 def DictComp_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def DictComp_get_generators(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'generators')
     if w_self.w_generators is None:
@@ -5412,7 +5337,7 @@
 
 def DictComp_set_generators(space, w_self, w_new_value):
     w_self.w_generators = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _DictComp_field_unroller = unrolling_iterable(['key', 'value', 'generators'])
 def DictComp_init(space, w_self, __args__):
@@ -5446,7 +5371,7 @@
         w_obj = w_self.getdictvalue(space, 'elt')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elt')
     return space.wrap(w_self.elt)
@@ -5454,16 +5379,18 @@
 def GeneratorExp_set_elt(space, w_self, w_new_value):
     try:
         w_self.elt = space.interp_w(expr, w_new_value, False)
+        if type(w_self.elt) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'elt', w_new_value)
         return
     w_self.deldictvalue(space, 'elt')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def GeneratorExp_get_generators(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'generators')
     if w_self.w_generators is None:
@@ -5477,7 +5404,7 @@
 
 def GeneratorExp_set_generators(space, w_self, w_new_value):
     w_self.w_generators = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _GeneratorExp_field_unroller = unrolling_iterable(['elt', 'generators'])
 def GeneratorExp_init(space, w_self, __args__):
@@ -5510,7 +5437,7 @@
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return space.wrap(w_self.value)
@@ -5518,13 +5445,15 @@
 def Yield_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, True)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Yield_field_unroller = unrolling_iterable(['value'])
 def Yield_init(space, w_self, __args__):
@@ -5555,7 +5484,7 @@
         w_obj = w_self.getdictvalue(space, 'left')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'left')
     return space.wrap(w_self.left)
@@ -5563,16 +5492,18 @@
 def Compare_set_left(space, w_self, w_new_value):
     try:
         w_self.left = space.interp_w(expr, w_new_value, False)
+        if type(w_self.left) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'left', w_new_value)
         return
     w_self.deldictvalue(space, 'left')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Compare_get_ops(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ops')
     if w_self.w_ops is None:
@@ -5586,10 +5517,10 @@
 
 def Compare_set_ops(space, w_self, w_new_value):
     w_self.w_ops = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def Compare_get_comparators(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'comparators')
     if w_self.w_comparators is None:
@@ -5603,7 +5534,7 @@
 
 def Compare_set_comparators(space, w_self, w_new_value):
     w_self.w_comparators = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _Compare_field_unroller = unrolling_iterable(['left', 'ops', 'comparators'])
 def Compare_init(space, w_self, __args__):
@@ -5638,7 +5569,7 @@
         w_obj = w_self.getdictvalue(space, 'func')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'func')
     return space.wrap(w_self.func)
@@ -5646,16 +5577,18 @@
 def Call_set_func(space, w_self, w_new_value):
     try:
         w_self.func = space.interp_w(expr, w_new_value, False)
+        if type(w_self.func) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'func', w_new_value)
         return
     w_self.deldictvalue(space, 'func')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Call_get_args(space, w_self):
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'args')
     if w_self.w_args is None:
@@ -5669,10 +5602,10 @@
 
 def Call_set_args(space, w_self, w_new_value):
     w_self.w_args = w_new_value
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def Call_get_keywords(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'keywords')
     if w_self.w_keywords is None:
@@ -5686,14 +5619,14 @@
 
 def Call_set_keywords(space, w_self, w_new_value):
     w_self.w_keywords = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 def Call_get_starargs(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'starargs')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 8:
+    if not w_self.initialization_state & 32:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'starargs')
     return space.wrap(w_self.starargs)
@@ -5701,20 +5634,22 @@
 def Call_set_starargs(space, w_self, w_new_value):
     try:
         w_self.starargs = space.interp_w(expr, w_new_value, True)
+        if type(w_self.starargs) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'starargs', w_new_value)
         return
     w_self.deldictvalue(space, 'starargs')
-    w_self.initialization_state |= 8
+    w_self.initialization_state |= 32
 
 def Call_get_kwargs(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'kwargs')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 16:
+    if not w_self.initialization_state & 64:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'kwargs')
     return space.wrap(w_self.kwargs)
@@ -5722,13 +5657,15 @@
 def Call_set_kwargs(space, w_self, w_new_value):
     try:
         w_self.kwargs = space.interp_w(expr, w_new_value, True)
+        if type(w_self.kwargs) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'kwargs', w_new_value)
         return
     w_self.deldictvalue(space, 'kwargs')
-    w_self.initialization_state |= 16
+    w_self.initialization_state |= 64
 
 _Call_field_unroller = unrolling_iterable(['func', 'args', 'keywords', 'starargs', 'kwargs'])
 def Call_init(space, w_self, __args__):
@@ -5765,7 +5702,7 @@
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return space.wrap(w_self.value)
@@ -5773,13 +5710,15 @@
 def Repr_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Repr_field_unroller = unrolling_iterable(['value'])
 def Repr_init(space, w_self, __args__):
@@ -5810,7 +5749,7 @@
         w_obj = w_self.getdictvalue(space, 'n')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'n')
     return w_self.n
@@ -5824,7 +5763,7 @@
         w_self.setdictvalue(space, 'n', w_new_value)
         return
     w_self.deldictvalue(space, 'n')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Num_field_unroller = unrolling_iterable(['n'])
 def Num_init(space, w_self, __args__):
@@ -5855,7 +5794,7 @@
         w_obj = w_self.getdictvalue(space, 's')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 's')
     return w_self.s
@@ -5869,7 +5808,7 @@
         w_self.setdictvalue(space, 's', w_new_value)
         return
     w_self.deldictvalue(space, 's')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Str_field_unroller = unrolling_iterable(['s'])
 def Str_init(space, w_self, __args__):
@@ -5900,7 +5839,7 @@
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return space.wrap(w_self.value)
@@ -5908,20 +5847,22 @@
 def Attribute_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Attribute_get_attr(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'attr')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'attr')
     return space.wrap(w_self.attr)
@@ -5935,14 +5876,14 @@
         w_self.setdictvalue(space, 'attr', w_new_value)
         return
     w_self.deldictvalue(space, 'attr')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def Attribute_get_ctx(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'ctx')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
     return expr_context_to_class[w_self.ctx - 1]()
@@ -5958,7 +5899,7 @@
         return
     # need to save the original object too
     w_self.setdictvalue(space, 'ctx', w_new_value)
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _Attribute_field_unroller = unrolling_iterable(['value', 'attr', 'ctx'])
 def Attribute_init(space, w_self, __args__):
@@ -5991,7 +5932,7 @@
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return space.wrap(w_self.value)
@@ -5999,20 +5940,22 @@
 def Subscript_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Subscript_get_slice(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'slice')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'slice')
     return space.wrap(w_self.slice)
@@ -6020,20 +5963,22 @@
 def Subscript_set_slice(space, w_self, w_new_value):
     try:
         w_self.slice = space.interp_w(slice, w_new_value, False)
+        if type(w_self.slice) is slice:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'slice', w_new_value)
         return
     w_self.deldictvalue(space, 'slice')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def Subscript_get_ctx(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'ctx')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
     return expr_context_to_class[w_self.ctx - 1]()
@@ -6049,7 +5994,7 @@
         return
     # need to save the original object too
     w_self.setdictvalue(space, 'ctx', w_new_value)
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _Subscript_field_unroller = unrolling_iterable(['value', 'slice', 'ctx'])
 def Subscript_init(space, w_self, __args__):
@@ -6082,7 +6027,7 @@
         w_obj = w_self.getdictvalue(space, 'id')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'id')
     return space.wrap(w_self.id)
@@ -6096,14 +6041,14 @@
         w_self.setdictvalue(space, 'id', w_new_value)
         return
     w_self.deldictvalue(space, 'id')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Name_get_ctx(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'ctx')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
     return expr_context_to_class[w_self.ctx - 1]()
@@ -6119,7 +6064,7 @@
         return
     # need to save the original object too
     w_self.setdictvalue(space, 'ctx', w_new_value)
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _Name_field_unroller = unrolling_iterable(['id', 'ctx'])
 def Name_init(space, w_self, __args__):
@@ -6147,7 +6092,7 @@
 )
 
 def List_get_elts(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elts')
     if w_self.w_elts is None:
@@ -6161,14 +6106,14 @@
 
 def List_set_elts(space, w_self, w_new_value):
     w_self.w_elts = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def List_get_ctx(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'ctx')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
     return expr_context_to_class[w_self.ctx - 1]()
@@ -6184,7 +6129,7 @@
         return
     # need to save the original object too
     w_self.setdictvalue(space, 'ctx', w_new_value)
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _List_field_unroller = unrolling_iterable(['elts', 'ctx'])
 def List_init(space, w_self, __args__):
@@ -6213,7 +6158,7 @@
 )
 
 def Tuple_get_elts(space, w_self):
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'elts')
     if w_self.w_elts is None:
@@ -6227,14 +6172,14 @@
 
 def Tuple_set_elts(space, w_self, w_new_value):
     w_self.w_elts = w_new_value
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def Tuple_get_ctx(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'ctx')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'ctx')
     return expr_context_to_class[w_self.ctx - 1]()
@@ -6250,7 +6195,7 @@
         return
     # need to save the original object too
     w_self.setdictvalue(space, 'ctx', w_new_value)
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 _Tuple_field_unroller = unrolling_iterable(['elts', 'ctx'])
 def Tuple_init(space, w_self, __args__):
@@ -6283,7 +6228,7 @@
         w_obj = w_self.getdictvalue(space, 'value')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'value')
     return w_self.value
@@ -6297,7 +6242,7 @@
         w_self.setdictvalue(space, 'value', w_new_value)
         return
     w_self.deldictvalue(space, 'value')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 _Const_field_unroller = unrolling_iterable(['value'])
 def Const_init(space, w_self, __args__):
@@ -6409,6 +6354,8 @@
 def Slice_set_lower(space, w_self, w_new_value):
     try:
         w_self.lower = space.interp_w(expr, w_new_value, True)
+        if type(w_self.lower) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
@@ -6430,6 +6377,8 @@
 def Slice_set_upper(space, w_self, w_new_value):
     try:
         w_self.upper = space.interp_w(expr, w_new_value, True)
+        if type(w_self.upper) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
@@ -6451,6 +6400,8 @@
 def Slice_set_step(space, w_self, w_new_value):
     try:
         w_self.step = space.interp_w(expr, w_new_value, True)
+        if type(w_self.step) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
@@ -6540,6 +6491,8 @@
 def Index_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
@@ -6809,6 +6762,8 @@
 def comprehension_set_target(space, w_self, w_new_value):
     try:
         w_self.target = space.interp_w(expr, w_new_value, False)
+        if type(w_self.target) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
@@ -6830,6 +6785,8 @@
 def comprehension_set_iter(space, w_self, w_new_value):
     try:
         w_self.iter = space.interp_w(expr, w_new_value, False)
+        if type(w_self.iter) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
@@ -6887,7 +6844,7 @@
         w_obj = w_self.getdictvalue(space, 'lineno')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & w_self._lineno_mask:
+    if not w_self.initialization_state & 1:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'lineno')
     return space.wrap(w_self.lineno)
@@ -6901,14 +6858,14 @@
         w_self.setdictvalue(space, 'lineno', w_new_value)
         return
     w_self.deldictvalue(space, 'lineno')
-    w_self.initialization_state |= w_self._lineno_mask
+    w_self.initialization_state |= 1
 
 def excepthandler_get_col_offset(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'col_offset')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & w_self._col_offset_mask:
+    if not w_self.initialization_state & 2:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'col_offset')
     return space.wrap(w_self.col_offset)
@@ -6922,7 +6879,7 @@
         w_self.setdictvalue(space, 'col_offset', w_new_value)
         return
     w_self.deldictvalue(space, 'col_offset')
-    w_self.initialization_state |= w_self._col_offset_mask
+    w_self.initialization_state |= 2
 
 excepthandler.typedef = typedef.TypeDef("excepthandler",
     AST.typedef,
@@ -6938,7 +6895,7 @@
         w_obj = w_self.getdictvalue(space, 'type')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 1:
+    if not w_self.initialization_state & 4:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'type')
     return space.wrap(w_self.type)
@@ -6946,20 +6903,22 @@
 def ExceptHandler_set_type(space, w_self, w_new_value):
     try:
         w_self.type = space.interp_w(expr, w_new_value, True)
+        if type(w_self.type) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'type', w_new_value)
         return
     w_self.deldictvalue(space, 'type')
-    w_self.initialization_state |= 1
+    w_self.initialization_state |= 4
 
 def ExceptHandler_get_name(space, w_self):
     if w_self.w_dict is not None:
         w_obj = w_self.getdictvalue(space, 'name')
         if w_obj is not None:
             return w_obj
-    if not w_self.initialization_state & 2:
+    if not w_self.initialization_state & 8:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'name')
     return space.wrap(w_self.name)
@@ -6967,16 +6926,18 @@
 def ExceptHandler_set_name(space, w_self, w_new_value):
     try:
         w_self.name = space.interp_w(expr, w_new_value, True)
+        if type(w_self.name) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
         w_self.setdictvalue(space, 'name', w_new_value)
         return
     w_self.deldictvalue(space, 'name')
-    w_self.initialization_state |= 2
+    w_self.initialization_state |= 8
 
 def ExceptHandler_get_body(space, w_self):
-    if not w_self.initialization_state & 4:
+    if not w_self.initialization_state & 16:
         typename = space.type(w_self).getname(space)
         raise operationerrfmt(space.w_AttributeError, "'%s' object has no attribute '%s'", typename, 'body')
     if w_self.w_body is None:
@@ -6990,7 +6951,7 @@
 
 def ExceptHandler_set_body(space, w_self, w_new_value):
     w_self.w_body = w_new_value
-    w_self.initialization_state |= 4
+    w_self.initialization_state |= 16
 
 _ExceptHandler_field_unroller = unrolling_iterable(['type', 'name', 'body'])
 def ExceptHandler_init(space, w_self, __args__):
@@ -7164,6 +7125,8 @@
 def keyword_set_value(space, w_self, w_new_value):
     try:
         w_self.value = space.interp_w(expr, w_new_value, False)
+        if type(w_self.value) is expr:
+            raise OperationError(space.w_TypeError, space.w_None)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
diff --git a/pypy/interpreter/astcompiler/optimize.py b/pypy/interpreter/astcompiler/optimize.py
--- a/pypy/interpreter/astcompiler/optimize.py
+++ b/pypy/interpreter/astcompiler/optimize.py
@@ -1,6 +1,5 @@
 """codegen helpers and AST constant folding."""
 import sys
-import itertools
 
 from pypy.interpreter.astcompiler import ast, consts, misc
 from pypy.tool import stdlib_opcode as ops
@@ -146,8 +145,7 @@
 }
 unrolling_unary_folders = unrolling_iterable(unary_folders.items())
 
-for folder in itertools.chain(binary_folders.itervalues(),
-                              unary_folders.itervalues()):
+for folder in binary_folders.values() + unary_folders.values():
     folder._always_inline_ = True
 del folder
 
diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py
--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
+++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
@@ -79,6 +79,7 @@
         else:
             self.emit("class %s(AST):" % (base,))
             if sum.attributes:
+                self.emit("")
                 args = ", ".join(attr.name.value for attr in sum.attributes)
                 self.emit("def __init__(self, %s):" % (args,), 1)
                 for attr in sum.attributes:
@@ -114,7 +115,7 @@
             else:
                 names.append(repr(field.name.value))
         sub = (", ".join(names), name.value)
-        self.emit("missing_field(space, self.initialization_state, [%s], %r)"
+        self.emit("self.missing_field(space, [%s], %r)"
                   % sub, 3)
         self.emit("else:", 2)
         # Fill in all the default fields.
@@ -195,17 +196,13 @@
     def visitConstructor(self, cons, base, extra_attributes):
         self.emit("class %s(%s):" % (cons.name, base))
         self.emit("")
-        for field in self.data.cons_attributes[cons]:
-            subst = (field.name, self.data.field_masks[field])
-            self.emit("_%s_mask = %i" % subst, 1)
-        self.emit("")
         self.make_constructor(cons.fields, cons, extra_attributes, base)
         self.emit("")
         self.emit("def walkabout(self, visitor):", 1)
         self.emit("visitor.visit_%s(self)" % (cons.name,), 2)
         self.emit("")
         self.make_mutate_over(cons, cons.name)
-        self.make_var_syncer(cons.fields + self.data.cons_attributes[cons],
+        self.make_var_syncer(self.data.cons_attributes[cons] + cons.fields,
                              cons, cons.name)
 
     def visitField(self, field):
@@ -324,7 +321,7 @@
 
     def visitSum(self, sum, name):
         for field in sum.attributes:
-            self.make_property(field, name, True)
+            self.make_property(field, name)
         self.make_typedef(name, "AST", sum.attributes,
                           fields_name="_attributes")
         if not is_simple_sum(sum):
@@ -400,13 +397,10 @@
     def visitField(self, field, name):
         self.make_property(field, name)
 
-    def make_property(self, field, name, different_masks=False):
+    def make_property(self, field, name):
         func = "def %s_get_%s(space, w_self):" % (name, field.name)
         self.emit(func)
-        if different_masks:
-            flag = "w_self._%s_mask" % (field.name,)
-        else:
-            flag = self.data.field_masks[field]
+        flag = self.data.field_masks[field]
         if not field.seq:
             self.emit("if w_self.w_dict is not None:", 1)
             self.emit("    w_obj = w_self.getdictvalue(space, '%s')" % (field.name,), 1)
@@ -458,6 +452,11 @@
                     config = (field.name, field.type, repr(field.opt))
                     self.emit("w_self.%s = space.interp_w(%s, w_new_value, %s)" %
                               config, 2)
+                    if field.type.value not in self.data.prod_simple:
+                        self.emit("if type(w_self.%s) is %s:" % (
+                                field.name, field.type), 2)
+                        self.emit("raise OperationError(space.w_TypeError, "
+                                  "space.w_None)", 3)
             else:
                 level = 2
                 if field.opt and field.type.value != "int":
@@ -505,7 +504,10 @@
             optional_mask = 0
             for i, field in enumerate(fields):
                 flag = 1 << i
-                field_masks[field] = flag
+                if field not in field_masks:
+                    field_masks[field] = flag
+                else:
+                    assert field_masks[field] == flag
                 if field.opt:
                     optional_mask |= flag
                 else:
@@ -518,9 +520,9 @@
                 if is_simple_sum(sum):
                     simple_types.add(tp.name.value)
                 else:
+                    attrs = [field for field in sum.attributes]
                     for cons in sum.types:
-                        attrs = [copy_field(field) for field in sum.attributes]
-                        add_masks(cons.fields + attrs, cons)
+                        add_masks(attrs + cons.fields, cons)
                         cons_attributes[cons] = attrs
             else:
                 prod = tp.value
@@ -588,6 +590,24 @@
             space.setattr(self, w_name,
                           space.getitem(w_state, w_name))
 
+    def missing_field(self, space, required, host):
+        "Find which required field is missing."
+        state = self.initialization_state
+        for i in range(len(required)):
+            if (state >> i) & 1:
+                continue  # field is present
+            missing = required[i]
+            if missing is None:
+                continue  # field is optional
+            w_obj = self.getdictvalue(space, missing)
+            if w_obj is None:
+                err = "required field \\"%s\\" missing from %s"
+                raise operationerrfmt(space.w_TypeError, err, missing, host)
+            else:
+                err = "incorrect type for field \\"%s\\" in %s"
+                raise operationerrfmt(space.w_TypeError, err, missing, host)
+        raise AssertionError("should not reach here")
+
 
 class NodeVisitorNotImplemented(Exception):
     pass
@@ -631,15 +651,6 @@
 )
 
 
-def missing_field(space, state, required, host):
-    "Find which required field is missing."
-    for i in range(len(required)):
-        if not (state >> i) & 1:
-            missing = required[i]
-            if missing is not None:
-                 err = "required field \\"%s\\" missing from %s"
-                 raise operationerrfmt(space.w_TypeError, err, missing, host)
-    raise AssertionError("should not reach here")
 
 
 """
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1,4 +1,3 @@
-import itertools
 import pypy
 from pypy.interpreter.executioncontext import ExecutionContext, ActionFlag
 from pypy.interpreter.executioncontext import UserDelAction, FrameTraceAction
@@ -188,6 +187,12 @@
 
     # -------------------------------------------------------------------
 
+    def is_w(self, space, w_other):
+        return self is w_other
+
+    def immutable_unique_id(self, space):
+        return None
+
     def str_w(self, space):
         w_msg = typed_unwrap_error_msg(space, "string", self)
         raise OperationError(space.w_TypeError, w_msg)
@@ -482,6 +487,16 @@
         'parser', 'fcntl', '_codecs', 'binascii'
     ]
 
+    # These modules are treated like CPython treats built-in modules,
+    # i.e. they always shadow any xx.py.  The other modules are treated
+    # like CPython treats extension modules, and are loaded in sys.path
+    # order by the fake entry '.../lib_pypy/__extensions__'.
+    MODULES_THAT_ALWAYS_SHADOW = dict.fromkeys([
+        '__builtin__', '__pypy__', '_ast', '_codecs', '_sre', '_warnings',
+        '_weakref', 'errno', 'exceptions', 'gc', 'imp', 'marshal',
+        'posix', 'nt', 'pwd', 'signal', 'sys', 'thread', 'zipimport',
+    ], None)
+
     def make_builtins(self):
         "NOT_RPYTHON: only for initializing the space."
 
@@ -513,8 +528,8 @@
         exception_types_w = self.export_builtin_exceptions()
 
         # initialize with "bootstrap types" from objspace  (e.g. w_None)
-        types_w = itertools.chain(self.get_builtin_types().iteritems(),
-                                  exception_types_w.iteritems())
+        types_w = (self.get_builtin_types().items() +
+                   exception_types_w.items())
         for name, w_type in types_w:
             self.setitem(self.builtin.w_dict, self.wrap(name), w_type)
 
@@ -681,9 +696,20 @@
         """shortcut for space.is_true(space.eq(w_obj1, w_obj2))"""
         return self.is_w(w_obj1, w_obj2) or self.is_true(self.eq(w_obj1, w_obj2))
 
-    def is_w(self, w_obj1, w_obj2):
-        """shortcut for space.is_true(space.is_(w_obj1, w_obj2))"""
-        return self.is_true(self.is_(w_obj1, w_obj2))
+    def is_(self, w_one, w_two):
+        return self.newbool(self.is_w(w_one, w_two))
+
+    def is_w(self, w_one, w_two):
+        # done by a method call on w_two (and not on w_one, because of the
+        # expected programming style where we say "if x is None" or
+        # "if x is object").
+        return w_two.is_w(self, w_one)
+
+    def id(self, w_obj):
+        w_result = w_obj.immutable_unique_id(self)
+        if w_result is None:
+            w_result = self.wrap(compute_unique_id(w_obj))
+        return w_result
 
     def hash_w(self, w_obj):
         """shortcut for space.int_w(space.hash(w_obj))"""
@@ -879,6 +905,16 @@
         """
         return self.unpackiterable(w_iterable, expected_length)
 
+    def listview_str(self, w_list):
+        """ Return a list of unwrapped strings out of a list of strings. If the
+        argument is not a list or does not contain only strings, return None.
+        May return None anyway.
+        """
+        return None
+
+    def newlist_str(self, list_s):
+        return self.newlist([self.wrap(s) for s in list_s])
+
     @jit.unroll_safe
     def exception_match(self, w_exc_type, w_check_class):
         """Checks if the given exception type matches 'w_check_class'."""
@@ -1013,9 +1049,6 @@
     def isinstance_w(self, w_obj, w_type):
         return self.is_true(self.isinstance(w_obj, w_type))
 
-    def id(self, w_obj):
-        return self.wrap(compute_unique_id(w_obj))
-
     # The code below only works
     # for the simple case (new-style instance).
     # These methods are patched with the full logic by the __builtin__
@@ -1587,6 +1620,8 @@
     'UnicodeError',
     'ValueError',
     'ZeroDivisionError',
+    'UnicodeEncodeError',
+    'UnicodeDecodeError',
     ]
 
 ## Irregular part of the interface:
diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py
--- a/pypy/interpreter/eval.py
+++ b/pypy/interpreter/eval.py
@@ -98,7 +98,6 @@
         "Abstract. Get the expected number of locals."
         raise TypeError, "abstract"
 
-    @jit.dont_look_inside
     def fast2locals(self):
         # Copy values from the fastlocals to self.w_locals
         if self.w_locals is None:
@@ -112,7 +111,6 @@
                 w_name = self.space.wrap(name)
                 self.space.setitem(self.w_locals, w_name, w_value)
 
-    @jit.dont_look_inside
     def locals2fast(self):
         # Copy values from self.w_locals to the fastlocals
         assert self.w_locals is not None
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -619,7 +619,8 @@
                                                   self.descr_reqcls,
                                                   args)
         except Exception, e:
-            raise self.handle_exception(space, e)
+            self.handle_exception(space, e)
+            w_result = None
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -655,7 +656,8 @@
                                                   self.descr_reqcls,
                                                   args)
         except Exception, e:
-            raise self.handle_exception(space, e)
+            self.handle_exception(space, e)
+            w_result = None
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -674,7 +676,8 @@
                                                   self.descr_reqcls,
                                                   args.prepend(w_obj))
         except Exception, e:
-            raise self.handle_exception(space, e)
+            self.handle_exception(space, e)
+            w_result = None
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -690,7 +693,8 @@
             raise OperationError(space.w_SystemError,
                                  space.wrap("unexpected DescrMismatch error"))
         except Exception, e:
-            raise self.handle_exception(space, e)
+            self.handle_exception(space, e)
+            w_result = None
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -708,7 +712,8 @@
                                            self.descr_reqcls,
                                            Arguments(space, [w1]))
         except Exception, e:
-            raise self.handle_exception(space, e)
+            self.handle_exception(space, e)
+            w_result = None
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -726,7 +731,8 @@
                                            self.descr_reqcls,
                                            Arguments(space, [w1, w2]))
         except Exception, e:
-            raise self.handle_exception(space, e)
+            self.handle_exception(space, e)
+            w_result = None
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -744,7 +750,8 @@
                                            self.descr_reqcls,
                                            Arguments(space, [w1, w2, w3]))
         except Exception, e:
-            raise self.handle_exception(space, e)
+            self.handle_exception(space, e)
+            w_result = None
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -763,7 +770,8 @@
                                            Arguments(space,
                                                      [w1, w2, w3, w4]))
         except Exception, e:
-            raise self.handle_exception(space, e)
+            self.handle_exception(space, e)
+            w_result = None
         if w_result is None:
             w_result = space.w_None
         return w_result
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -1,8 +1,9 @@
+from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.error import OperationError
-from pypy.interpreter.baseobjspace import Wrappable
 from pypy.interpreter.gateway import NoneNotWrapped
+from pypy.interpreter.pyopcode import LoopBlock
 from pypy.rlib import jit
-from pypy.interpreter.pyopcode import LoopBlock
+from pypy.rlib.objectmodel import specialize
 
 
 class GeneratorIterator(Wrappable):
@@ -156,38 +157,43 @@
                     break
                 block = block.previous
 
-    def unpack_into(self, results_w):
-        """This is a hack for performance: runs the generator and collects
-        all produced items in a list."""
-        # XXX copied and simplified version of send_ex()
-        space = self.space
-        if self.running:
-            raise OperationError(space.w_ValueError,
-                                 space.wrap('generator already executing'))
-        frame = self.frame
-        if frame is None:    # already finished
-            return
-        self.running = True
-        try:
-            pycode = self.pycode
-            while True:
-                jitdriver.jit_merge_point(self=self, frame=frame,
-                                          results_w=results_w,
-                                          pycode=pycode)
-                try:
-                    w_result = frame.execute_frame(space.w_None)
-                except OperationError, e:
-                    if not e.match(space, space.w_StopIteration):
-                        raise
-                    break
-                # if the frame is now marked as finished, it was RETURNed from
-                if frame.frame_finished_execution:
-                    break
-                results_w.append(w_result)     # YIELDed
-        finally:
-            frame.f_backref = jit.vref_None
-            self.running = False
-            self.frame = None
-
-jitdriver = jit.JitDriver(greens=['pycode'],
-                          reds=['self', 'frame', 'results_w'])
+    # Results can be either an RPython list of W_Root, or it can be an
+    # app-level W_ListObject, which also has an append() method, that's why we
+    # generate 2 versions of the function and 2 jit drivers.
+    def _create_unpack_into():
+        jitdriver = jit.JitDriver(greens=['pycode'],
+                                  reds=['self', 'frame', 'results'])
+        def unpack_into(self, results):
+            """This is a hack for performance: runs the generator and collects
+            all produced items in a list."""
+            # XXX copied and simplified version of send_ex()
+            space = self.space
+            if self.running:
+                raise OperationError(space.w_ValueError,
+                                     space.wrap('generator already executing'))
+            frame = self.frame
+            if frame is None:    # already finished
+                return
+            self.running = True
+            try:
+                pycode = self.pycode
+                while True:
+                    jitdriver.jit_merge_point(self=self, frame=frame,
+                                              results=results, pycode=pycode)
+                    try:
+                        w_result = frame.execute_frame(space.w_None)
+                    except OperationError, e:
+                        if not e.match(space, space.w_StopIteration):
+                            raise
+                        break
+                    # if the frame is now marked as finished, it was RETURNed from
+                    if frame.frame_finished_execution:
+                        break
+                    results.append(w_result)     # YIELDed
+            finally:
+                frame.f_backref = jit.vref_None
+                self.running = False
+                self.frame = None
+        return unpack_into
+    unpack_into = _create_unpack_into()
+    unpack_into_w = _create_unpack_into()
\ No newline at end of file
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -10,7 +10,7 @@
 from pypy.rlib.objectmodel import we_are_translated, instantiate
 from pypy.rlib.jit import hint
 from pypy.rlib.debug import make_sure_not_resized, check_nonneg
-from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rarithmetic import intmask, r_uint
 from pypy.rlib import jit
 from pypy.tool import stdlib_opcode
 from pypy.tool.stdlib_opcode import host_bytecode_spec
@@ -167,7 +167,7 @@
                 # Execution starts just after the last_instr.  Initially,
                 # last_instr is -1.  After a generator suspends it points to
                 # the YIELD_VALUE instruction.
-                next_instr = self.last_instr + 1
+                next_instr = r_uint(self.last_instr + 1)
                 if next_instr != 0:
                     self.pushvalue(w_inputvalue)
             #
@@ -691,6 +691,7 @@
     handlerposition = space.int_w(w_handlerposition)
     valuestackdepth = space.int_w(w_valuestackdepth)
     assert valuestackdepth >= 0
+    assert handlerposition >= 0
     blk = instantiate(get_block_class(opname))
     blk.handlerposition = handlerposition
     blk.valuestackdepth = valuestackdepth
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -837,6 +837,7 @@
         raise Yield
 
     def jump_absolute(self, jumpto, next_instr, ec):
+        check_nonneg(jumpto)
         return jumpto
 
     def JUMP_FORWARD(self, jumpby, next_instr):
@@ -1278,7 +1279,7 @@
 
     def handle(self, frame, unroller):
         next_instr = self.really_handle(frame, unroller)   # JIT hack
-        return next_instr
+        return r_uint(next_instr)
 
     def really_handle(self, frame, unroller):
         """ Purely abstract method
diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py
--- a/pypy/interpreter/test/test_executioncontext.py
+++ b/pypy/interpreter/test/test_executioncontext.py
@@ -292,7 +292,7 @@
         import os, sys
         print sys.executable, self.tmpfile
         if sys.platform == "win32":
-            cmdformat = '""%s" "%s""'    # excellent! tons of "!
+            cmdformat = '"%s" "%s"'
         else:
             cmdformat = "'%s' '%s'"
         g = os.popen(cmdformat % (sys.executable, self.tmpfile), 'r')
diff --git a/pypy/interpreter/test/test_function.py b/pypy/interpreter/test/test_function.py
--- a/pypy/interpreter/test/test_function.py
+++ b/pypy/interpreter/test/test_function.py
@@ -587,7 +587,7 @@
         assert isinstance(meth2, Method)
         assert meth2.call_args(args) == obj1
         # Check method returned from unbound_method.__get__()
-        w_meth3 = descr_function_get(space, func, None, space.type(obj2))
+        w_meth3 = descr_function_get(space, func, space.w_None, space.type(obj2))
         meth3 = space.unwrap(w_meth3)
         w_meth4 = meth3.descr_method_get(obj2, space.w_None)
         meth4 = space.unwrap(w_meth4)
diff --git a/pypy/interpreter/test/test_objspace.py b/pypy/interpreter/test/test_objspace.py
--- a/pypy/interpreter/test/test_objspace.py
+++ b/pypy/interpreter/test/test_objspace.py
@@ -63,10 +63,13 @@
     def test_unpackiterable(self):
         space = self.space
         w = space.wrap
-        l = [w(1), w(2), w(3), w(4)]
+        l = [space.newlist([]) for l in range(4)]
         w_l = space.newlist(l)
-        assert space.unpackiterable(w_l) == l
-        assert space.unpackiterable(w_l, 4) == l
+        l1 = space.unpackiterable(w_l)
+        l2 = space.unpackiterable(w_l, 4)
+        for i in range(4):
+            assert space.is_w(l1[i], l[i])
+            assert space.is_w(l2[i], l[i])
         err = raises(OperationError, space.unpackiterable, w_l, 3)
         assert err.value.match(space, space.w_ValueError)
         err = raises(OperationError, space.unpackiterable, w_l, 5)
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -54,7 +54,11 @@
 #  Hash support
 
 def default_identity_hash(space, w_obj):
-    return space.wrap(compute_identity_hash(w_obj))
+    w_unique_id = w_obj.immutable_unique_id(space)
+    if w_unique_id is None:     # common case
+        return space.wrap(compute_identity_hash(w_obj))
+    else:
+        return space.hash(w_unique_id)
 
 # ____________________________________________________________
 #
diff --git a/pypy/jit/backend/arm/arch.py b/pypy/jit/backend/arm/arch.py
--- a/pypy/jit/backend/arm/arch.py
+++ b/pypy/jit/backend/arm/arch.py
@@ -1,10 +1,9 @@
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.rarithmetic import r_uint
-from pypy.rpython.lltypesystem import lltype
 
 
-FUNC_ALIGN=8
-WORD=4
+FUNC_ALIGN = 8
+WORD = 4
 
 # the number of registers that we need to save around malloc calls
 N_REGISTERS_SAVED_BY_MALLOC = 9
@@ -27,18 +26,22 @@
 }
 """])
 
-arm_int_div_sign = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
+
 def arm_int_div_emulator(a, b):
-    return int(a/float(b))
+    return int(a / float(b))
+arm_int_div_sign = lltype.Ptr(
+        lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
 arm_int_div = rffi.llexternal(
     "pypy__arm_int_div", [lltype.Signed, lltype.Signed], lltype.Signed,
                         _callable=arm_int_div_emulator,
                         compilation_info=eci,
                         _nowrapper=True, elidable_function=True)
 
-arm_uint_div_sign = lltype.Ptr(lltype.FuncType([lltype.Unsigned, lltype.Unsigned], lltype.Unsigned))
+
 def arm_uint_div_emulator(a, b):
-    return r_uint(a)/r_uint(b)
+    return r_uint(a) / r_uint(b)
+arm_uint_div_sign = lltype.Ptr(
+        lltype.FuncType([lltype.Unsigned, lltype.Unsigned], lltype.Unsigned))
 arm_uint_div = rffi.llexternal(
     "pypy__arm_uint_div", [lltype.Unsigned, lltype.Unsigned], lltype.Unsigned,
                         _callable=arm_uint_div_emulator,
@@ -46,7 +49,6 @@
                         _nowrapper=True, elidable_function=True)
 
 
-arm_int_mod_sign = arm_int_div_sign
 def arm_int_mod_emulator(a, b):
     sign = 1
     if a < 0:
@@ -56,9 +58,9 @@
         b = -1 * b
     res = a % b
     return sign * res
+arm_int_mod_sign = arm_int_div_sign
 arm_int_mod = rffi.llexternal(
     "pypy__arm_int_mod", [lltype.Signed, lltype.Signed], lltype.Signed,
                         _callable=arm_int_mod_emulator,
                         compilation_info=eci,
                         _nowrapper=True, elidable_function=True)
-
diff --git a/pypy/jit/backend/arm/assembler.py b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -1,41 +1,36 @@
 from __future__ import with_statement
 import os
-from pypy.jit.backend.arm.helper.assembler import saved_registers, count_reg_args, \
+from pypy.jit.backend.arm.helper.assembler import saved_registers, \
+                                                    count_reg_args, \
                                                     decode32, encode32, \
-                                                    decode64, encode64
+                                                    decode64
 from pypy.jit.backend.arm import conditions as c
-from pypy.jit.backend.arm import locations
 from pypy.jit.backend.arm import registers as r
-from pypy.jit.backend.arm.arch import WORD, FUNC_ALIGN, PC_OFFSET, N_REGISTERS_SAVED_BY_MALLOC
+from pypy.jit.backend.arm.arch import WORD, FUNC_ALIGN, \
+                                    PC_OFFSET, N_REGISTERS_SAVED_BY_MALLOC
 from pypy.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder
-from pypy.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager, ARMv7RegisterMananger,
-                                        _check_imm_arg, TempInt,
-                                        TempPtr,
-                                        operations as regalloc_operations,
-                                        operations_with_guard as regalloc_operations_with_guard)
+from pypy.jit.backend.arm.regalloc import (Regalloc, ARMFrameManager,
+                    ARMv7RegisterManager, check_imm_arg,
+                    operations as regalloc_operations,
+                    operations_with_guard as regalloc_operations_with_guard)
 from pypy.jit.backend.arm.jump import remap_frame_layout
-from pypy.jit.backend.llsupport.regalloc import compute_vars_longevity, TempBox
 from pypy.jit.backend.llsupport.asmmemmgr import MachineDataBlockWrapper
 from pypy.jit.backend.model import CompiledLoopToken
 from pypy.jit.codewriter import longlong
-from pypy.jit.metainterp.history import (Const, ConstInt, ConstPtr,
-                                        BoxInt, BoxPtr, AbstractFailDescr,
-                                        INT, REF, FLOAT)
+from pypy.jit.metainterp.history import (AbstractFailDescr, INT, REF, FLOAT)
 from pypy.jit.metainterp.resoperation import rop
 from pypy.rlib import rgc
 from pypy.rlib.objectmodel import we_are_translated
-from pypy.rlib.rarithmetic import r_uint, r_longlong
-from pypy.rlib.longlong2float import float2longlong, longlong2float
 from pypy.rpython.annlowlevel import llhelper
 from pypy.rpython.lltypesystem import lltype, rffi, llmemory
 from pypy.rpython.lltypesystem.lloperation import llop
-from pypy.jit.backend.arm.opassembler import ResOpAssembler, GuardToken
-from pypy.rlib.debug import (debug_print, debug_start, debug_stop,
-                             have_debug_prints)
+from pypy.jit.backend.arm.opassembler import ResOpAssembler
+from pypy.rlib.debug import debug_print, debug_start, debug_stop
 
 # XXX Move to llsupport
 from pypy.jit.backend.x86.support import values_array, memcpy_fn
 
+
 class AssemblerARM(ResOpAssembler):
     """
     Encoding for locations in memory
@@ -52,8 +47,8 @@
     \xFF = END_OF_LOCS
     """
     FLOAT_TYPE = '\xED'
-    REF_TYPE   = '\xEE'
-    INT_TYPE   = '\xEF'
+    REF_TYPE = '\xEE'
+    INT_TYPE = '\xEF'
 
     STACK_LOC = '\xFC'
     IMM_LOC = '\xFD'
@@ -62,20 +57,18 @@
 
     END_OF_LOCS = '\xFF'
 
+    STACK_FIXED_AREA = -1
 
     def __init__(self, cpu, failargs_limit=1000):
         self.cpu = cpu
         self.fail_boxes_int = values_array(lltype.Signed, failargs_limit)
-        self.fail_boxes_float = values_array(longlong.FLOATSTORAGE, failargs_limit)
+        self.fail_boxes_float = values_array(longlong.FLOATSTORAGE,
+                                                            failargs_limit)
         self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit)
         self.fail_boxes_count = 0
         self.fail_force_index = 0
         self.setup_failure_recovery()
         self.mc = None
-        self.malloc_func_addr = 0
-        self.malloc_array_func_addr = 0
-        self.malloc_str_func_addr = 0
-        self.malloc_unicode_func_addr = 0
         self.memcpy_addr = 0
         self.pending_guards = None
         self._exit_code_addr = 0
@@ -84,10 +77,22 @@
         self._regalloc = None
         self.datablockwrapper = None
         self.propagate_exception_path = 0
+        self._compute_stack_size()
+
+    def _compute_stack_size(self):
+        self.STACK_FIXED_AREA = len(r.callee_saved_registers) * WORD
+        self.STACK_FIXED_AREA += WORD  # FORCE_TOKEN
+        self.STACK_FIXED_AREA += N_REGISTERS_SAVED_BY_MALLOC * WORD
+        if self.cpu.supports_floats:
+            self.STACK_FIXED_AREA += (len(r.callee_saved_vfp_registers)
+                                        * 2 * WORD)
+        if self.STACK_FIXED_AREA % 8 != 0:
+            self.STACK_FIXED_AREA += WORD  # Stack alignment
+        assert self.STACK_FIXED_AREA % 8 == 0
 
     def setup(self, looptoken, operations):
         self.current_clt = looptoken.compiled_loop_token
-        operations = self.cpu.gc_ll_descr.rewrite_assembler(self.cpu, 
+        operations = self.cpu.gc_ll_descr.rewrite_assembler(self.cpu,
                         operations, self.current_clt.allgcrefs)
         assert self.memcpy_addr != 0, 'setup_once() not called?'
         self.mc = ARMv7Builder()
@@ -96,6 +101,7 @@
         allblocks = self.get_asmmemmgr_blocks(looptoken)
         self.datablockwrapper = MachineDataBlockWrapper(self.cpu.asmmemmgr,
                                                         allblocks)
+        self.target_tokens_currently_compiling = {}
         return operations
 
     def teardown(self):
@@ -109,28 +115,15 @@
         # Addresses of functions called by new_xxx operations
         gc_ll_descr = self.cpu.gc_ll_descr
         gc_ll_descr.initialize()
-        ll_new = gc_ll_descr.get_funcptr_for_new()
-        self.malloc_func_addr = rffi.cast(lltype.Signed, ll_new)
         self._build_propagate_exception_path()
-        if gc_ll_descr.get_funcptr_for_newarray is not None:
-            ll_new_array = gc_ll_descr.get_funcptr_for_newarray()
-            self.malloc_array_func_addr = rffi.cast(lltype.Signed,
-                                                    ll_new_array)
-        if gc_ll_descr.get_funcptr_for_newstr is not None:
-            ll_new_str = gc_ll_descr.get_funcptr_for_newstr()
-            self.malloc_str_func_addr = rffi.cast(lltype.Signed,
-                                                  ll_new_str)
-        if gc_ll_descr.get_funcptr_for_newunicode is not None:
-            ll_new_unicode = gc_ll_descr.get_funcptr_for_newunicode()
-            self.malloc_unicode_func_addr = rffi.cast(lltype.Signed,
-                                                      ll_new_unicode)
         if gc_ll_descr.get_malloc_slowpath_addr is not None:
             self._build_malloc_slowpath()
         if gc_ll_descr.gcrootmap and gc_ll_descr.gcrootmap.is_shadow_stack:
             self._build_release_gil(gc_ll_descr.gcrootmap)
         self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
         self._exit_code_addr = self._gen_exit_path()
-        self._leave_jitted_hook_save_exc = self._gen_leave_jitted_hook_code(True)
+        self._leave_jitted_hook_save_exc = \
+                                    self._gen_leave_jitted_hook_code(True)
         self._leave_jitted_hook = self._gen_leave_jitted_hook_code(False)
 
     @staticmethod
@@ -146,16 +139,17 @@
             after()
 
     _NOARG_FUNC = lltype.Ptr(lltype.FuncType([], lltype.Void))
+
     def _build_release_gil(self, gcrootmap):
         assert gcrootmap.is_shadow_stack
         releasegil_func = llhelper(self._NOARG_FUNC,
                                    self._release_gil_shadowstack)
         reacqgil_func = llhelper(self._NOARG_FUNC,
                                  self._reacquire_gil_shadowstack)
-        self.releasegil_addr  = rffi.cast(lltype.Signed, releasegil_func)
+        self.releasegil_addr = rffi.cast(lltype.Signed, releasegil_func)
         self.reacqgil_addr = rffi.cast(lltype.Signed, reacqgil_func)
 
-    def _gen_leave_jitted_hook_code(self, save_exc=False):
+    def _gen_leave_jitted_hook_code(self, save_exc):
         mc = ARMv7Builder()
         # XXX add a check if cpu supports floats
         with saved_registers(mc, r.caller_resp + [r.ip], r.caller_vfp_resp):
@@ -174,7 +168,8 @@
         # call on_leave_jitted_save_exc()
         # XXX add a check if cpu supports floats
         with saved_registers(mc, r.caller_resp + [r.ip], r.caller_vfp_resp):
-            addr = self.cpu.get_on_leave_jitted_int(save_exception=True)
+            addr = self.cpu.get_on_leave_jitted_int(save_exception=True,
+                                                default_to_memoryerror=True)
             mc.BL(addr)
         mc.gen_load_int(r.ip.value, self.cpu.propagate_exception_v)
         mc.MOV_rr(r.r0.value, r.ip.value)
@@ -186,34 +181,37 @@
         @rgc.no_collect
         def failure_recovery_func(mem_loc, frame_pointer, stack_pointer):
             """mem_loc is a structure in memory describing where the values for
-            the failargs are stored.
-            frame loc is the address of the frame pointer for the frame to be
-            decoded frame """
-            return self.decode_registers_and_descr(mem_loc, frame_pointer, stack_pointer)
+            the failargs are stored.  frame loc is the address of the frame
+            pointer for the frame to be decoded frame """
+            return self.decode_registers_and_descr(mem_loc,
+                                            frame_pointer, stack_pointer)
 
         self.failure_recovery_func = failure_recovery_func
 
-    recovery_func_sign = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Signed, lltype.Signed], lltype.Signed))
+    recovery_func_sign = lltype.Ptr(lltype.FuncType([lltype.Signed,
+                                lltype.Signed, lltype.Signed], lltype.Signed))
 
     @rgc.no_collect
     def decode_registers_and_descr(self, mem_loc, frame_loc, regs_loc):
-        """Decode locations encoded in memory at mem_loc and write the values to
-        the failboxes.
-        Values for spilled vars and registers are stored on stack at frame_loc
-        """
-        #XXX check if units are correct here, when comparing words and bytes and stuff
-        # assert 0, 'check if units are correct here, when comparing words and bytes and stuff'
+        """Decode locations encoded in memory at mem_loc and write the values
+        to the failboxes.  Values for spilled vars and registers are stored on
+        stack at frame_loc """
+        # XXX check if units are correct here, when comparing words and bytes
+        # and stuff assert 0, 'check if units are correct here, when comparing
+        # words and bytes and stuff'
 
         enc = rffi.cast(rffi.CCHARP, mem_loc)
-        frame_depth = frame_loc - (regs_loc + len(r.all_regs)*WORD + len(r.all_vfp_regs)*2*WORD)
+        frame_depth = frame_loc - (regs_loc + len(r.all_regs)
+                            * WORD + len(r.all_vfp_regs) * 2 * WORD)
         assert (frame_loc - frame_depth) % 4 == 0
         stack = rffi.cast(rffi.CCHARP, frame_loc - frame_depth)
         assert regs_loc % 4 == 0
         vfp_regs = rffi.cast(rffi.CCHARP, regs_loc)
-        assert (regs_loc + len(r.all_vfp_regs)*2*WORD) % 4 == 0
+        assert (regs_loc + len(r.all_vfp_regs) * 2 * WORD) % 4 == 0
         assert frame_depth >= 0
 
-        regs = rffi.cast(rffi.CCHARP, regs_loc + len(r.all_vfp_regs)*2*WORD)
+        regs = rffi.cast(rffi.CCHARP,
+                    regs_loc + len(r.all_vfp_regs) * 2 * WORD)
         i = -1
         fail_index = -1
         while(True):
@@ -231,49 +229,52 @@
             if res == self.IMM_LOC:
                 # imm value
                 if group == self.INT_TYPE or group == self.REF_TYPE:
-                    value = decode32(enc, i+1)
+                    value = decode32(enc, i + 1)
                     i += 4
                 else:
                     assert group == self.FLOAT_TYPE
-                    adr = decode32(enc, i+1)
-                    value = rffi.cast(rffi.CArrayPtr(longlong.FLOATSTORAGE), adr)[0]
+                    adr = decode32(enc, i + 1)
+                    tp = rffi.CArrayPtr(longlong.FLOATSTORAGE)
+                    value = rffi.cast(tp, adr)[0]
                     self.fail_boxes_float.setitem(fail_index, value)
                     i += 4
                     continue
             elif res == self.STACK_LOC:
-                stack_loc = decode32(enc, i+1)
+                stack_loc = decode32(enc, i + 1)
                 i += 4
                 if group == self.FLOAT_TYPE:
-                    value = decode64(stack, frame_depth - stack_loc*WORD)
+                    value = decode64(stack,
+                            frame_depth - (stack_loc + 1) * WORD)
+                    fvalue = rffi.cast(longlong.FLOATSTORAGE, value)
+                    self.fail_boxes_float.setitem(fail_index, fvalue)
+                    continue
+                else:
+                    value = decode32(stack, frame_depth - stack_loc * WORD)
+            else:  # REG_LOC
+                reg = ord(enc[i])
+                if group == self.FLOAT_TYPE:
+                    value = decode64(vfp_regs, reg * 2 * WORD)
                     self.fail_boxes_float.setitem(fail_index, value)
                     continue
                 else:
-                    value = decode32(stack, frame_depth - stack_loc*WORD)
-            else: # REG_LOC
-                reg = ord(enc[i])
-                if group == self.FLOAT_TYPE:
-                    value = decode64(vfp_regs, reg*2*WORD)
-                    self.fail_boxes_float.setitem(fail_index, value)
-                    continue
-                else:
-                    value = decode32(regs, reg*WORD)
+                    value = decode32(regs, reg * WORD)
 
             if group == self.INT_TYPE:
                 self.fail_boxes_int.setitem(fail_index, value)
             elif group == self.REF_TYPE:
+                assert (value & 3) == 0, "misaligned pointer"
                 tgt = self.fail_boxes_ptr.get_addr_for_num(fail_index)
                 rffi.cast(rffi.LONGP, tgt)[0] = value
             else:
                 assert 0, 'unknown type'
 
-
         assert enc[i] == self.END_OF_LOCS
-        descr = decode32(enc, i+1)
+        descr = decode32(enc, i + 1)
         self.fail_boxes_count = fail_index
         self.fail_force_index = frame_loc
         return descr
 
-    def decode_inputargs(self, enc, regalloc):
+    def decode_inputargs(self, enc):
         locs = []
         j = 0
         while enc[j] != self.END_OF_LOCS:
@@ -282,7 +283,8 @@
                 j += 1
                 continue
 
-            assert res in [self.FLOAT_TYPE, self.INT_TYPE, self.REF_TYPE], 'location type is not supported'
+            assert res in [self.FLOAT_TYPE, self.INT_TYPE, self.REF_TYPE], \
+                        'location type is not supported'
             res_type = res
             j += 1
             res = enc[j]
@@ -296,10 +298,10 @@
                     t = INT
                 else:
                     t = REF
-                stack_loc = decode32(enc, j+1)
-                loc = regalloc.frame_manager.frame_pos(stack_loc, t)
+                stack_loc = decode32(enc, j + 1)
+                loc = ARMFrameManager.frame_pos(stack_loc, t)
                 j += 4
-            else: # REG_LOC
+            else:  # REG_LOC
                 if res_type == self.FLOAT_TYPE:
                     loc = r.all_vfp_regs[ord(res)]
                 else:
@@ -309,7 +311,6 @@
         return locs
 
     def _build_malloc_slowpath(self):
-        gcrootmap = self.cpu.gc_ll_descr.gcrootmap
         mc = ARMv7Builder()
         assert self.cpu.supports_floats
         # We need to push two registers here because we are going to make a
@@ -321,10 +322,10 @@
             mc.SUB_rr(r.r0.value, r.r1.value, r.r0.value)
             addr = self.cpu.gc_ll_descr.get_malloc_slowpath_addr()
             # XXX replace with an STMxx operation
-            for reg, ofs in ARMv7RegisterMananger.REGLOC_TO_COPY_AREA_OFS.items():
+            for reg, ofs in ARMv7RegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
                 mc.STR_ri(reg.value, r.fp.value, imm=ofs)
             mc.BL(addr)
-            for reg, ofs in ARMv7RegisterMananger.REGLOC_TO_COPY_AREA_OFS.items():
+            for reg, ofs in ARMv7RegisterManager.REGLOC_TO_COPY_AREA_OFS.items():
                 mc.LDR_ri(reg.value, r.fp.value, imm=ofs)
 
         mc.CMP_ri(r.r0.value, 0)
@@ -349,13 +350,16 @@
 
     def _gen_exit_path(self):
         mc = ARMv7Builder()
-        decode_registers_addr = llhelper(self.recovery_func_sign, self.failure_recovery_func)
-        
+        decode_registers_addr = llhelper(self.recovery_func_sign,
+                                            self.failure_recovery_func)
         self._insert_checks(mc)
         with saved_registers(mc, r.all_regs, r.all_vfp_regs):
-            mc.MOV_rr(r.r0.value, r.ip.value) # move mem block address, to r0 to pass as
-            mc.MOV_rr(r.r1.value, r.fp.value) # pass the current frame pointer as second param
-            mc.MOV_rr(r.r2.value, r.sp.value) # pass the current stack pointer as third param
+            # move mem block address, to r0 to pass as
+            mc.MOV_rr(r.r0.value, r.ip.value)
+            # pass the current frame pointer as second param
+            mc.MOV_rr(r.r1.value, r.fp.value)
+            # pass the current stack pointer as third param
+            mc.MOV_rr(r.r2.value, r.sp.value)
             self._insert_checks(mc)
             mc.BL(rffi.cast(lltype.Signed, decode_registers_addr))
             mc.MOV_rr(r.ip.value, r.r0.value)
@@ -374,15 +378,15 @@
         # 1 separator byte
         # 4 bytes for the faildescr
         # const floats are stored in memory and the box contains the address
-        memsize = (len(arglocs)-1)*6+5
+        memsize = (len(arglocs) - 1) * 6 + 5
         memaddr = self.datablockwrapper.malloc_aligned(memsize, alignment=1)
         mem = rffi.cast(rffi.CArrayPtr(lltype.Char), memaddr)
         i = 0
         j = 0
         while i < len(args):
-            if arglocs[i+1]:
+            if arglocs[i + 1]:
                 arg = args[i]
-                loc = arglocs[i+1]
+                loc = arglocs[i + 1]
                 if arg.type == INT:
                     mem[j] = self.INT_TYPE
                     j += 1
@@ -402,12 +406,18 @@
                     assert (arg.type == INT or arg.type == REF
                                 or arg.type == FLOAT)
                     mem[j] = self.IMM_LOC
-                    encode32(mem, j+1, loc.getint())
+                    encode32(mem, j + 1, loc.getint())
                     j += 5
                 else:
                     assert loc.is_stack()
                     mem[j] = self.STACK_LOC
-                    encode32(mem, j+1, loc.position)
+                    if arg.type == FLOAT:
+                        # Float locs store the location number with an offset
+                        # of 1 -.- so we need to take this into account here
+                        # when generating the encoding
+                        encode32(mem, j + 1, loc.position - 1)
+                    else:
+                        encode32(mem, j + 1, loc.position)
                     j += 5
             else:
                 mem[j] = self.EMPTY_LOC
@@ -417,15 +427,18 @@
         mem[j] = chr(0xFF)
 
         n = self.cpu.get_fail_descr_number(descr)
-        encode32(mem, j+1, n)
+        encode32(mem, j + 1, n)
         return memaddr
 
-    def _gen_path_to_exit_path(self, descr, args, arglocs, fcond=c.AL, save_exc=False):
+    def _gen_path_to_exit_path(self, descr, args, arglocs,
+                                            save_exc, fcond=c.AL):
+        assert isinstance(save_exc, bool)
         memaddr = self.gen_descr_encoding(descr, args, arglocs)
-        self.gen_exit_code(self.mc, memaddr, fcond, save_exc)
+        self.gen_exit_code(self.mc, memaddr, save_exc, fcond)
         return memaddr
 
-    def gen_exit_code(self, mc, memaddr, fcond=c.AL, save_exc=False):
+    def gen_exit_code(self, mc, memaddr, save_exc, fcond=c.AL):
+        assert isinstance(save_exc, bool)
         self.mc.gen_load_int(r.ip.value, memaddr)
         #mc.LDR_ri(r.ip.value, r.pc.value, imm=WORD)
         if save_exc:
@@ -440,30 +453,36 @@
             self.mc.writechar(chr(0))
 
     def gen_func_epilog(self, mc=None, cond=c.AL):
+        stack_size = self.STACK_FIXED_AREA
+        stack_size -= len(r.callee_saved_registers) * WORD
+        if self.cpu.supports_floats:
+            stack_size -= len(r.callee_saved_vfp_registers) * 2 * WORD
+
         gcrootmap = self.cpu.gc_ll_descr.gcrootmap
         if mc is None:
             mc = self.mc
         if gcrootmap and gcrootmap.is_shadow_stack:
             self.gen_footer_shadowstack(gcrootmap, mc)
-        offset = 1
+        mc.MOV_rr(r.sp.value, r.fp.value, cond=cond)
+        mc.ADD_ri(r.sp.value, r.sp.value, stack_size, cond=cond)
         if self.cpu.supports_floats:
-            offset += 1 # to keep stack alignment
-        mc.MOV_rr(r.sp.value, r.fp.value, cond=cond)
-        mc.ADD_ri(r.sp.value, r.sp.value, (N_REGISTERS_SAVED_BY_MALLOC+offset)*WORD, cond=cond)
-        if self.cpu.supports_floats:
-            mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers], cond=cond)
+            mc.VPOP([reg.value for reg in r.callee_saved_vfp_registers],
+                                                                    cond=cond)
         mc.POP([reg.value for reg in r.callee_restored_registers], cond=cond)
 
     def gen_func_prolog(self):
+        stack_size = self.STACK_FIXED_AREA
+        stack_size -= len(r.callee_saved_registers) * WORD
+        if self.cpu.supports_floats:
+            stack_size -= len(r.callee_saved_vfp_registers) * 2 * WORD
+
         self.mc.PUSH([reg.value for reg in r.callee_saved_registers])
-        offset = 1
         if self.cpu.supports_floats:
             self.mc.VPUSH([reg.value for reg in r.callee_saved_vfp_registers])
-            offset +=1 # to keep stack alignment
         # here we modify the stack pointer to leave room for the 9 registers
         # that are going to be saved here around malloc calls and one word to
         # store the force index
-        self.mc.SUB_ri(r.sp.value, r.sp.value, (N_REGISTERS_SAVED_BY_MALLOC+offset)*WORD)
+        self.mc.SUB_ri(r.sp.value, r.sp.value, stack_size)
         self.mc.MOV_rr(r.fp.value, r.sp.value)
         gcrootmap = self.cpu.gc_ll_descr.gcrootmap
         if gcrootmap and gcrootmap.is_shadow_stack:
@@ -475,191 +494,86 @@
         # XXX add some comments
         rst = gcrootmap.get_root_stack_top_addr()
         self.mc.gen_load_int(r.ip.value, rst)
-        self.mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop]
-        self.mc.ADD_ri(r.r5.value, r.r4.value, imm=2*WORD) # ADD r5, r4 [2*WORD]
+        self.mc.LDR_ri(r.r4.value, r.ip.value)  # LDR r4, [rootstacktop]
+        self.mc.ADD_ri(r.r5.value, r.r4.value,
+                                    imm=2 * WORD)  # ADD r5, r4 [2*WORD]
         self.mc.gen_load_int(r.r6.value, gcrootmap.MARKER)
         self.mc.STR_ri(r.r6.value, r.r4.value)
-        self.mc.STR_ri(r.fp.value, r.r4.value, WORD) 
+        self.mc.STR_ri(r.fp.value, r.r4.value, WORD)
         self.mc.STR_ri(r.r5.value, r.ip.value)
 
     def gen_footer_shadowstack(self, gcrootmap, mc):
         rst = gcrootmap.get_root_stack_top_addr()
         mc.gen_load_int(r.ip.value, rst)
-        mc.LDR_ri(r.r4.value, r.ip.value) # LDR r4, [rootstacktop]
-        mc.SUB_ri(r.r5.value, r.r4.value, imm=2*WORD) # ADD r5, r4 [2*WORD]
+        mc.LDR_ri(r.r4.value, r.ip.value)  # LDR r4, [rootstacktop]
+        mc.SUB_ri(r.r5.value, r.r4.value, imm=2 * WORD)  # ADD r5, r4 [2*WORD]
         mc.STR_ri(r.r5.value, r.ip.value)
 
-    def gen_bootstrap_code(self, nonfloatlocs, floatlocs, inputargs):
-        for i in range(len(nonfloatlocs)):
-            loc = nonfloatlocs[i]
-            if loc is None:
-                continue
-            arg = inputargs[i]
-            assert arg.type != FLOAT
-            if arg.type == REF:
-                addr = self.fail_boxes_ptr.get_addr_for_num(i)
-            elif arg.type == INT:
-                addr = self.fail_boxes_int.get_addr_for_num(i)
-            else:
-                assert 0
-            if loc.is_reg():
-                reg = loc
-            else:
-                reg = r.ip
-            self.mc.gen_load_int(reg.value, addr)
-            self.mc.LDR_ri(reg.value, reg.value)
-            if loc.is_stack():
-                self.mov_loc_loc(r.ip, loc)
-        for i in range(len(floatlocs)):
-            loc = floatlocs[i]
-            if loc is None:
-                continue
-            arg = inputargs[i]
-            assert arg.type == FLOAT
-            addr = self.fail_boxes_float.get_addr_for_num(i)
-            self.mc.gen_load_int(r.ip.value, addr)
-            if loc.is_vfp_reg():
-                self.mc.VLDR(loc.value, r.ip.value)
-            else:
-                self.mc.VLDR(r.vfp_ip.value, r.ip.value)
-                self.mov_loc_loc(r.vfp_ip, loc)
-
-    def gen_direct_bootstrap_code(self, loop_head, looptoken, inputargs):
-        self.gen_func_prolog()
-        nonfloatlocs, floatlocs = looptoken._arm_arglocs
-
-        reg_args = count_reg_args(inputargs)
-
-        stack_locs = len(inputargs) - reg_args
-
-        selected_reg = 0
-        count = 0
-        float_args = []
-        nonfloat_args = []
-        nonfloat_regs = []
-        # load reg args
-        for i in range(reg_args):
-            arg = inputargs[i]
-            if arg.type == FLOAT and count % 2 != 0:
-                    selected_reg += 1
-                    count = 0
-            reg = r.all_regs[selected_reg]
-
-            if arg.type == FLOAT:
-                float_args.append((reg, floatlocs[i]))
-            else:
-                nonfloat_args.append(reg)
-                nonfloat_regs.append(nonfloatlocs[i])
-
-            if arg.type == FLOAT:
-                selected_reg += 2
-            else:
-                selected_reg += 1
-                count += 1
-
-        # move float arguments to vfp regsiters
-        for loc, vfp_reg in float_args:
-            self.mov_to_vfp_loc(loc, r.all_regs[loc.value+1], vfp_reg)
-
-        # remap values stored in core registers
-        remap_frame_layout(self, nonfloat_args, nonfloat_regs, r.ip)
-
-        # load values passed on the stack to the corresponding locations
-        stack_position = len(r.callee_saved_registers)*WORD + \
-                            len(r.callee_saved_vfp_registers)*2*WORD + \
-                            N_REGISTERS_SAVED_BY_MALLOC * WORD + \
-                            2 * WORD # for the FAIL INDEX and the stack padding
-        count = 0
-        for i in range(reg_args, len(inputargs)):
-            arg = inputargs[i]
-            if arg.type == FLOAT:
-                loc = floatlocs[i]
-            else:
-                loc = nonfloatlocs[i]
-            if loc.is_reg():
-                self.mc.LDR_ri(loc.value, r.fp.value, stack_position)
-                count += 1
-            elif loc.is_vfp_reg():
-                if count % 2 != 0:
-                    stack_position += WORD
-                    count = 0
-                self.mc.VLDR(loc.value, r.fp.value, stack_position)
-            elif loc.is_stack():
-                if loc.type == FLOAT:
-                    if count % 2 != 0:
-                        stack_position += WORD
-                        count = 0
-                    self.mc.VLDR(r.vfp_ip.value, r.fp.value, stack_position)
-                    self.mov_loc_loc(r.vfp_ip, loc)
-                elif loc.type == INT or loc.type == REF:
-                    count += 1
-                    self.mc.LDR_ri(r.ip.value, r.fp.value, stack_position)
-                    self.mov_loc_loc(r.ip, loc)
-                else:
-                    assert 0, 'invalid location'
-            else:
-                assert 0, 'invalid location'
-            if loc.type == FLOAT:
-                size = 2
-            else:
-                size = 1
-            stack_position += size * WORD
-
-        sp_patch_location = self._prepare_sp_patch_position()
-        self.mc.B_offs(loop_head)
-        self._patch_sp_offset(sp_patch_location, looptoken._arm_frame_depth)
-
     def _dump(self, ops, type='loop'):
         debug_start('jit-backend-ops')
         debug_print(type)
         for op in ops:
             debug_print(op.repr())
         debug_stop('jit-backend-ops')
+
+    def _call_header(self):
+        self.align()
+        self.gen_func_prolog()
+
     # cpu interface
     def assemble_loop(self, inputargs, operations, looptoken, log):
-
         clt = CompiledLoopToken(self.cpu, looptoken.number)
         clt.allgcrefs = []
         looptoken.compiled_loop_token = clt
+        clt._debug_nbargs = len(inputargs)
+
+        if not we_are_translated():
+            # Arguments should be unique
+            assert len(set(inputargs)) == len(inputargs)
 
         operations = self.setup(looptoken, operations)
         self._dump(operations)
-        longevity = compute_vars_longevity(inputargs, operations)
-        regalloc = Regalloc(longevity, assembler=self, frame_manager=ARMFrameManager())
 
+        self._call_header()
+        sp_patch_location = self._prepare_sp_patch_position()
 
-        self.align()
-        self.gen_func_prolog()
-        sp_patch_location = self._prepare_sp_patch_position()
-        nonfloatlocs, floatlocs = regalloc.prepare_loop(inputargs, operations, looptoken)
-        self.gen_bootstrap_code(nonfloatlocs, floatlocs, inputargs)
-        looptoken._arm_arglocs = [nonfloatlocs, floatlocs]
+        regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager())
+        regalloc.prepare_loop(inputargs, operations)
+
         loop_head = self.mc.currpos()
+        looptoken._arm_loop_code = loop_head
 
-        looptoken._arm_loop_code = loop_head
-        looptoken._arm_bootstrap_code = 0
-
-        self._walk_operations(operations, regalloc)
-
-        looptoken._arm_frame_depth = regalloc.frame_manager.frame_depth
-        self._patch_sp_offset(sp_patch_location, looptoken._arm_frame_depth)
-
-        self.align()
-
-        direct_bootstrap_code = self.mc.currpos()
-        self.gen_direct_bootstrap_code(loop_head, looptoken, inputargs)
+        clt.frame_depth = -1
+        frame_depth = self._assemble(operations, regalloc)
+        clt.frame_depth = frame_depth
+        self._patch_sp_offset(sp_patch_location, frame_depth)
 
         self.write_pending_failure_recoveries()
-        loop_start = self.materialize_loop(looptoken)
-        looptoken._arm_bootstrap_code = loop_start
-        looptoken._arm_direct_bootstrap_code = loop_start + direct_bootstrap_code
-        self.process_pending_guards(loop_start)
+
+        rawstart = self.materialize_loop(looptoken)
+        looptoken._arm_func_addr = rawstart
+
+        self.process_pending_guards(rawstart)
+        self.fixup_target_tokens(rawstart)
+
         if log and not we_are_translated():
             print 'Loop', inputargs, operations
-            self.mc._dump_trace(loop_start, 'loop_%s.asm' % self.cpu.total_compiled_loops)
+            self.mc._dump_trace(rawstart,
+                    'loop_%s.asm' % self.cpu.total_compiled_loops)
             print 'Done assembling loop with token %r' % looptoken
         self.teardown()
 
+    def _assemble(self, operations, regalloc):
+        regalloc.compute_hint_frame_locations(operations)
+        #self.mc.BKPT()
+        self._walk_operations(operations, regalloc)
+        frame_depth = regalloc.frame_manager.get_frame_depth()
+        jump_target_descr = regalloc.jump_target_descr
+        if jump_target_descr is not None:
+            frame_depth = max(frame_depth,
+                                jump_target_descr._arm_clt.frame_depth)
+        return frame_depth
+
     def assemble_bridge(self, faildescr, inputargs, operations,
                                                     original_loop_token, log):
         operations = self.setup(original_loop_token, operations)
@@ -667,32 +581,47 @@
         assert isinstance(faildescr, AbstractFailDescr)
         code = faildescr._failure_recovery_code
         enc = rffi.cast(rffi.CCHARP, code)
-        longevity = compute_vars_longevity(inputargs, operations)
-        regalloc = Regalloc(longevity, assembler=self,
-                                            frame_manager=ARMFrameManager())
+        frame_depth = faildescr._arm_current_frame_depth
+        arglocs = self.decode_inputargs(enc)
+        if not we_are_translated():
+            assert len(inputargs) == len(arglocs)
+
+        regalloc = Regalloc(assembler=self, frame_manager=ARMFrameManager())
+        regalloc.prepare_bridge(inputargs, arglocs, operations)
 
         sp_patch_location = self._prepare_sp_patch_position()
-        frame_depth = faildescr._arm_frame_depth
-        locs = self.decode_inputargs(enc, regalloc)
-        assert len(inputargs) == len(locs)
-        regalloc.update_bindings(locs, frame_depth, inputargs)
 
-        self._walk_operations(operations, regalloc)
+        frame_depth = self._assemble(operations, regalloc)
 
-        #original_loop_token._arm_frame_depth = regalloc.frame_manager.frame_depth
-        self._patch_sp_offset(sp_patch_location, regalloc.frame_manager.frame_depth)
+        self._patch_sp_offset(sp_patch_location, frame_depth)
 
         self.write_pending_failure_recoveries()
-        bridge_start = self.materialize_loop(original_loop_token)
-        self.process_pending_guards(bridge_start)
+        rawstart = self.materialize_loop(original_loop_token)
+        self.process_pending_guards(rawstart)
 
-        self.patch_trace(faildescr, original_loop_token, bridge_start, regalloc)
-        if log and not we_are_translated():
-            print 'Bridge', inputargs, operations
-            self.mc._dump_trace(bridge_start, 'bridge_%d.asm' %
-            self.cpu.total_compiled_bridges)
+        self.patch_trace(faildescr, original_loop_token,
+                                    rawstart, regalloc)
+        self.fixup_target_tokens(rawstart)
+
+        if not we_are_translated():
+            # for the benefit of tests
+            faildescr._arm_bridge_frame_depth = frame_depth
+            if log:
+                print 'Bridge', inputargs, operations
+                self.mc._dump_trace(rawstart, 'bridge_%d.asm' %
+                self.cpu.total_compiled_bridges)
+        self.current_clt.frame_depth = max(self.current_clt.frame_depth,
+                                                                frame_depth)
         self.teardown()
 
+    def fixup_target_tokens(self, rawstart):
+        for targettoken in self.target_tokens_currently_compiling:
+            targettoken._arm_loop_code += rawstart
+        self.target_tokens_currently_compiling = None
+
+    def target_arglocs(self, loop_token):
+        return loop_token._arm_arglocs
+
     def materialize_loop(self, looptoken):
         self.datablockwrapper.done()      # finish using cpu.asmmemmgr
         self.datablockwrapper = None
@@ -705,12 +634,12 @@
             descr = tok.descr
             #generate the exit stub and the encoded representation
             pos = self.mc.currpos()
-            tok.pos_recovery_stub = pos 
+            tok.pos_recovery_stub = pos
 
             memaddr = self._gen_path_to_exit_path(descr, tok.failargs,
-                                            tok.faillocs, save_exc=tok.save_exc)
+                                        tok.faillocs, save_exc=tok.save_exc)
             # store info on the descr
-            descr._arm_frame_depth = tok.faillocs[0].getint()
+            descr._arm_current_frame_depth = tok.faillocs[0].getint()
             descr._failure_recovery_code = memaddr
             descr._arm_guard_pos = pos
 
@@ -725,13 +654,15 @@
 
             if not tok.is_invalidate:
                 #patch the guard jumpt to the stub
-                # overwrite the generate NOP with a B_offs to the pos of the stub
+                # overwrite the generate NOP with a B_offs to the pos of the
+                # stub
                 mc = ARMv7Builder()
-                mc.B_offs(descr._arm_guard_pos - tok.offset, c.get_opposite_of(tok.fcond))
+                mc.B_offs(descr._arm_guard_pos - tok.offset,
+                                    c.get_opposite_of(tok.fcond))
                 mc.copy_to_raw_memory(block_start + tok.offset)
             else:
                 clt.invalidate_positions.append(
-                    (block_start + tok.offset, descr._arm_guard_pos - tok.offset))
+                (block_start + tok.offset, descr._arm_guard_pos - tok.offset))
 
     def get_asmmemmgr_blocks(self, looptoken):
         clt = looptoken.compiled_loop_token
@@ -740,21 +671,22 @@
         return clt.asmmemmgr_blocks
 
     def _prepare_sp_patch_position(self):
-        """Generate NOPs as placeholder to patch the instruction(s) to update the
-        sp according to the number of spilled variables"""
-        size = (self.mc.size_of_gen_load_int+WORD)
+        """Generate NOPs as placeholder to patch the instruction(s) to update
+        the sp according to the number of spilled variables"""
+        size = (self.mc.size_of_gen_load_int + WORD)
         l = self.mc.currpos()
-        for _ in range(size//WORD):
+        for _ in range(size // WORD):
             self.mc.NOP()
         return l
 
     def _patch_sp_offset(self, pos, frame_depth):
-        cb = OverwritingBuilder(self.mc, pos, OverwritingBuilder.size_of_gen_load_int+WORD)
+        cb = OverwritingBuilder(self.mc, pos,
+                                OverwritingBuilder.size_of_gen_load_int + WORD)
         # Note: the frame_depth is one less than the value stored in the frame
         # manager
         if frame_depth == 1:
             return
-        n = (frame_depth-1)*WORD
+        n = (frame_depth - 1) * WORD
 
         # ensure the sp is 8 byte aligned when patching it
         if n % 8 != 0:
@@ -784,7 +716,7 @@
                 cb.SUB_rr(r.sp.value, base_reg.value, r.ip.value, cond=fcond)
 
     def _walk_operations(self, operations, regalloc):
-        fcond=c.AL
+        fcond = c.AL
         self._regalloc = regalloc
         while regalloc.position() < len(operations) - 1:
             regalloc.next_instruction()
@@ -794,20 +726,28 @@
             if op.has_no_side_effect() and op.result not in regalloc.longevity:
                 regalloc.possibly_free_vars_for_op(op)
             elif self.can_merge_with_next_guard(op, i, operations):
+                guard = operations[i + 1]
+                assert guard.is_guard()
+                arglocs = regalloc_operations_with_guard[opnum](regalloc, op,
+                                        guard, fcond)
+                fcond = asm_operations_with_guard[opnum](self, op,
+                                        guard, arglocs, regalloc, fcond)
                 regalloc.next_instruction()
-                arglocs = regalloc_operations_with_guard[opnum](regalloc, op,
-                                        operations[i+1], fcond)
-                fcond = asm_operations_with_guard[opnum](self, op,
-                                        operations[i+1], arglocs, regalloc, fcond)
+                regalloc.possibly_free_vars_for_op(guard)
+                regalloc.possibly_free_vars(guard.getfailargs())
             elif not we_are_translated() and op.getopnum() == -124:
                 regalloc.prepare_force_spill(op, fcond)
             else:
                 arglocs = regalloc_operations[opnum](regalloc, op, fcond)
                 if arglocs is not None:
-                    fcond = asm_operations[opnum](self, op, arglocs, regalloc, fcond)
+                    fcond = asm_operations[opnum](self, op, arglocs,
+                                                        regalloc, fcond)
+            if op.is_guard():
+                regalloc.possibly_free_vars(op.getfailargs())
             if op.result:
                 regalloc.possibly_free_var(op.result)
             regalloc.possibly_free_vars_for_op(op)
+            regalloc.free_temp_vars()
             regalloc._check_invariants()
 
     # from ../x86/regalloc.py
@@ -847,7 +787,7 @@
         if size == 4:
             return
         if size == 1:
-            if not signed: #unsigned char
+            if not signed:  # unsigned char
                 self.mc.AND_ri(resloc.value, resloc.value, 0xFF)
             else:
                 self.mc.LSL_ri(resloc.value, resloc.value, 24)
@@ -856,9 +796,6 @@
             if not signed:
                 self.mc.LSL_ri(resloc.value, resloc.value, 16)
                 self.mc.LSR_ri(resloc.value, resloc.value, 16)
-                #self.mc.MOV_ri(r.ip.value, 0xFF)
-                #self.mc.ORR_ri(r.ip.value, 0xCFF)
-                #self.mc.AND_rr(resloc.value, resloc.value, r.ip.value)
             else:
                 self.mc.LSL_ri(resloc.value, resloc.value, 16)
                 self.mc.ASR_ri(resloc.value, resloc.value, 16)
@@ -873,7 +810,7 @@
 
     # regalloc support
     def load(self, loc, value):
-        assert (loc.is_reg() and value.is_imm() 
+        assert (loc.is_reg() and value.is_imm()
                     or loc.is_vfp_reg() and value.is_imm_float())
         if value.is_imm():
             self.mc.gen_load_int(loc.value, value.getint())
@@ -907,44 +844,49 @@
                 temp = r.lr
             else:
                 temp = r.ip
-            offset = ConstInt(loc.position*WORD)
-            if not _check_imm_arg(offset, size=0xFFF):
+            offset = loc.position * WORD
+            if not check_imm_arg(offset, size=0xFFF):
                 self.mc.PUSH([temp.value], cond=cond)
-                self.mc.gen_load_int(temp.value, -offset.value, cond=cond)
-                self.mc.STR_rr(prev_loc.value, r.fp.value, temp.value, cond=cond)
+                self.mc.gen_load_int(temp.value, -offset, cond=cond)
+                self.mc.STR_rr(prev_loc.value, r.fp.value,
+                                            temp.value, cond=cond)
                 self.mc.POP([temp.value], cond=cond)
             else:
-                self.mc.STR_ri(prev_loc.value, r.fp.value, imm=-1*offset.value, cond=cond)
+                self.mc.STR_ri(prev_loc.value, r.fp.value,
+                                            imm=-offset, cond=cond)
         else:
             assert 0, 'unsupported case'
 
     def _mov_stack_to_loc(self, prev_loc, loc, cond=c.AL):
         pushed = False
         if loc.is_reg():
-            assert prev_loc.type != FLOAT, 'trying to load from an incompatible location into a core register'
-            assert loc is not r.lr, 'lr is not supported as a target when moving from the stack'
+            assert prev_loc.type != FLOAT, 'trying to load from an \
+                incompatible location into a core register'
+            assert loc is not r.lr, 'lr is not supported as a target \
+                when moving from the stack'
             # unspill a core register
-            offset = ConstInt(prev_loc.position*WORD)
-            if not _check_imm_arg(offset, size=0xFFF):
+            offset = prev_loc.position * WORD
+            if not check_imm_arg(offset, size=0xFFF):
                 self.mc.PUSH([r.lr.value], cond=cond)
                 pushed = True
-                self.mc.gen_load_int(r.lr.value, -offset.value, cond=cond)
+                self.mc.gen_load_int(r.lr.value, -offset, cond=cond)
                 self.mc.LDR_rr(loc.value, r.fp.value, r.lr.value, cond=cond)
             else:
-                self.mc.LDR_ri(loc.value, r.fp.value, imm=-offset.value, cond=cond)
+                self.mc.LDR_ri(loc.value, r.fp.value, imm=-offset, cond=cond)
             if pushed:
                 self.mc.POP([r.lr.value], cond=cond)
         elif loc.is_vfp_reg():
-            assert prev_loc.type == FLOAT, 'trying to load from an incompatible location into a float register'
+            assert prev_loc.type == FLOAT, 'trying to load from an \
+                incompatible location into a float register'
             # load spilled value into vfp reg
-            offset = ConstInt(prev_loc.position*WORD)
+            offset = prev_loc.position * WORD
             self.mc.PUSH([r.ip.value], cond=cond)
             pushed = True
-            if not _check_imm_arg(offset):
-                self.mc.gen_load_int(r.ip.value, offset.value, cond=cond)
+            if not check_imm_arg(offset):
+                self.mc.gen_load_int(r.ip.value, offset, cond=cond)
                 self.mc.SUB_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond)
             else:
-                self.mc.SUB_ri(r.ip.value, r.fp.value, offset.value, cond=cond)
+                self.mc.SUB_ri(r.ip.value, r.fp.value, offset, cond=cond)
             self.mc.VLDR(loc.value, r.ip.value, cond=cond)
             if pushed:
                 self.mc.POP([r.ip.value], cond=cond)
@@ -963,15 +905,16 @@
         if loc.is_vfp_reg():
             self.mc.VMOV_cc(loc.value, prev_loc.value, cond=cond)
         elif loc.is_stack():
-            assert loc.type == FLOAT, 'trying to store to an incompatible location from a float register'
+            assert loc.type == FLOAT, 'trying to store to an \
+                incompatible location from a float register'
             # spill vfp register
             self.mc.PUSH([r.ip.value], cond=cond)
-            offset = ConstInt(loc.position*WORD)
-            if not _check_imm_arg(offset):
-                self.mc.gen_load_int(r.ip.value, offset.value, cond=cond)
+            offset = loc.position * WORD
+            if not check_imm_arg(offset):
+                self.mc.gen_load_int(r.ip.value, offset, cond=cond)
                 self.mc.SUB_rr(r.ip.value, r.fp.value, r.ip.value, cond=cond)
             else:
-                self.mc.SUB_ri(r.ip.value, r.fp.value, offset.value, cond=cond)
+                self.mc.SUB_ri(r.ip.value, r.fp.value, offset, cond=cond)
             self.mc.VSTR(prev_loc.value, r.ip.value, cond=cond)
             self.mc.POP([r.ip.value], cond=cond)
         else:
@@ -1009,17 +952,18 @@
             self.mc.POP([r.ip.value], cond=cond)
         elif vfp_loc.is_stack() and vfp_loc.type == FLOAT:
             # load spilled vfp value into two core registers
-            offset = ConstInt((vfp_loc.position)*WORD)
-            if not _check_imm_arg(offset, size=0xFFF):
+            offset = vfp_loc.position * WORD
+            if not check_imm_arg(offset, size=0xFFF):
                 self.mc.PUSH([r.ip.value], cond=cond)
-                self.mc.gen_load_int(r.ip.value, -offset.value, cond=cond)
+                self.mc.gen_load_int(r.ip.value, -offset, cond=cond)
                 self.mc.LDR_rr(reg1.value, r.fp.value, r.ip.value, cond=cond)
                 self.mc.ADD_ri(r.ip.value, r.ip.value, imm=WORD, cond=cond)
                 self.mc.LDR_rr(reg2.value, r.fp.value, r.ip.value, cond=cond)
                 self.mc.POP([r.ip.value], cond=cond)
             else:
-                self.mc.LDR_ri(reg1.value, r.fp.value, imm=-offset.value, cond=cond)
-                self.mc.LDR_ri(reg2.value, r.fp.value, imm=-offset.value+WORD, cond=cond)
+                self.mc.LDR_ri(reg1.value, r.fp.value, imm=-offset, cond=cond)
+                self.mc.LDR_ri(reg2.value, r.fp.value,
+                                                imm=-offset + WORD, cond=cond)
         else:
             assert 0, 'unsupported case'
 
@@ -1031,17 +975,18 @@
             self.mc.VMOV_cr(vfp_loc.value, reg1.value, reg2.value, cond=cond)
         elif vfp_loc.is_stack():
             # move from two core registers to a float stack location
-            offset = ConstInt((vfp_loc.position)*WORD)
-            if not _check_imm_arg(offset, size=0xFFF):
+            offset = vfp_loc.position * WORD
+            if not check_imm_arg(offset, size=0xFFF):
                 self.mc.PUSH([r.ip.value], cond=cond)
-                self.mc.gen_load_int(r.ip.value, -offset.value, cond=cond)
+                self.mc.gen_load_int(r.ip.value, -offset, cond=cond)
                 self.mc.STR_rr(reg1.value, r.fp.value, r.ip.value, cond=cond)
                 self.mc.ADD_ri(r.ip.value, r.ip.value, imm=WORD, cond=cond)
                 self.mc.STR_rr(reg2.value, r.fp.value, r.ip.value, cond=cond)
                 self.mc.POP([r.ip.value], cond=cond)
             else:
-                self.mc.STR_ri(reg1.value, r.fp.value, imm=-offset.value, cond=cond)
-                self.mc.STR_ri(reg2.value, r.fp.value, imm=-offset.value+WORD, cond=cond)
+                self.mc.STR_ri(reg1.value, r.fp.value, imm=-offset, cond=cond)
+                self.mc.STR_ri(reg2.value, r.fp.value,
+                                                imm=-offset + WORD, cond=cond)
         else:
             assert 0, 'unsupported case'
 
@@ -1092,14 +1037,15 @@
         llop.gc_assume_young_pointers(lltype.Void,
                                       llmemory.cast_ptr_to_adr(ptrs))
 
-    def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, tid):
+    def malloc_cond(self, nursery_free_adr, nursery_top_adr, size):
+        assert size & (WORD-1) == 0     # must be correctly aligned
         size = max(size, self.cpu.gc_ll_descr.minimal_size_in_nursery)
-        size = (size + WORD-1) & ~(WORD-1)     # round up
+        size = (size + WORD - 1) & ~(WORD - 1)     # round up
 
         self.mc.gen_load_int(r.r0.value, nursery_free_adr)
         self.mc.LDR_ri(r.r0.value, r.r0.value)
 
-        if _check_imm_arg(ConstInt(size)):
+        if check_imm_arg(size):
             self.mc.ADD_ri(r.r1.value, r.r0.value, size)
         else:
             self.mc.gen_load_int(r.r1.value, size)
@@ -1136,10 +1082,6 @@
         self.mc.gen_load_int(r.ip.value, nursery_free_adr)
         self.mc.STR_ri(r.r1.value, r.ip.value)
 
-        self.mc.gen_load_int(r.ip.value, tid)
-        self.mc.STR_ri(r.ip.value, r.r0.value)
-
-
     def mark_gc_roots(self, force_index, use_copy_area=False):
         if force_index < 0:
             return     # not needed
@@ -1163,14 +1105,18 @@
         else:
             return 0
 
+
 def not_implemented(msg):
     os.write(2, '[ARM/asm] %s\n' % msg)
     raise NotImplementedError(msg)
 
+
 def notimplemented_op(self, op, arglocs, regalloc, fcond):
-    raise NotImplementedError, op
+    raise NotImplementedError(op)
+
+
 def notimplemented_op_with_guard(self, op, guard_op, arglocs, regalloc, fcond):
-    raise NotImplementedError, op
+    raise NotImplementedError(op)
 
 asm_operations = [notimplemented_op] * (rop._LAST + 1)
 asm_operations_with_guard = [notimplemented_op_with_guard] * (rop._LAST + 1)
@@ -1192,4 +1138,3 @@
     if hasattr(AssemblerARM, methname):
         func = getattr(AssemblerARM, methname).im_func
         asm_operations_with_guard[value] = func
-
diff --git a/pypy/jit/backend/arm/codebuilder.py b/pypy/jit/backend/arm/codebuilder.py
--- a/pypy/jit/backend/arm/codebuilder.py
+++ b/pypy/jit/backend/arm/codebuilder.py
@@ -3,18 +3,22 @@
 from pypy.jit.backend.arm import registers as reg
 from pypy.jit.backend.arm.arch import (WORD, FUNC_ALIGN)
 from pypy.jit.backend.arm.instruction_builder import define_instructions
-
-from pypy.rlib.rmmap import alloc, PTR
-from pypy.rpython.annlowlevel import llhelper
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.jit.metainterp.history import ConstInt, BoxInt, AbstractFailDescr
+from pypy.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
 from pypy.rlib.objectmodel import we_are_translated
-from pypy.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
+from pypy.rpython.lltypesystem import lltype, rffi, llmemory
 from pypy.tool.udir import udir
 
+clear_cache = rffi.llexternal(
+    "__clear_cache",
+    [llmemory.Address, llmemory.Address],
+    lltype.Void,
+    _nowrapper=True,
+    sandboxsafe=True)
+
+
 def binary_helper_call(name):
-    signature = getattr(arch, 'arm_%s_sign' % name)
     function = getattr(arch, 'arm_%s' % name)
+
     def f(self, c=cond.AL):
         """Generates a call to a helper function, takes its
         arguments in r0 and r1, result is placed in r0"""
@@ -24,9 +28,10 @@
         else:
             self.PUSH(range(2, 4), cond=c)
             self.BL(addr, c)
-            self.POP(range(2,4), cond=c)
+            self.POP(range(2, 4), cond=c)
     return f
 
+
 class AbstractARMv7Builder(object):
 
     def __init__(self):
@@ -35,6 +40,7 @@
     def align(self):
         while(self.currpos() % FUNC_ALIGN != 0):
             self.writechar(chr(0))
+
     def NOP(self):
         self.MOV_rr(0, 0)
 
@@ -72,7 +78,7 @@
                 | 0xB << 8
                 | nregs)
         self.write32(instr)
-    
+
     def VMOV_rc(self, rt, rt2, dm, cond=cond.AL):
         """This instruction copies two words from two ARM core registers into a
         doubleword extension register, or from a doubleword extension register
@@ -109,7 +115,7 @@
         self.write32(instr)
 
     def VMOV_cc(self, dd, dm, cond=cond.AL):
-        sz = 1 # for 64-bit mode
+        sz = 1  # for 64-bit mode
         instr = (cond << 28
                 | 0xEB << 20
                 | (dd & 0xF) << 12
@@ -156,10 +162,8 @@
         self.write32(cond << 28 | 0xEF1FA10)
 
     def B(self, target, c=cond.AL):
-        #assert self._fits_in_24bits(target)
-        #return (c << 20 | 0xA << 24 | target & 0xFFFFFF)
         if c == cond.AL:
-            self.LDR_ri(reg.pc.value, reg.pc.value, -arch.PC_OFFSET/2)
+            self.LDR_ri(reg.pc.value, reg.pc.value, -arch.PC_OFFSET / 2)
             self.write32(target)
         else:
             self.gen_load_int(reg.ip.value, target, cond=c)
@@ -173,8 +177,8 @@
 
     def BL(self, target, c=cond.AL):
         if c == cond.AL:
-            self.ADD_ri(reg.lr.value, reg.pc.value, arch.PC_OFFSET/2)
-            self.LDR_ri(reg.pc.value, reg.pc.value, imm=-arch.PC_OFFSET/2)
+            self.ADD_ri(reg.lr.value, reg.pc.value, arch.PC_OFFSET / 2)
+            self.LDR_ri(reg.pc.value, reg.pc.value, imm=-arch.PC_OFFSET / 2)
             self.write32(target)
         else:
             self.gen_load_int(reg.ip.value, target, cond=c)
@@ -228,7 +232,6 @@
     def currpos(self):
         raise NotImplementedError
 
-    size_of_gen_load_int = 2 * WORD
     def gen_load_int(self, r, value, cond=cond.AL):
         """r is the register number, value is the value to be loaded to the
         register"""
@@ -237,6 +240,8 @@
         self.MOVW_ri(r, bottom, cond)
         if top:
             self.MOVT_ri(r, top, cond)
+    size_of_gen_load_int = 2 * WORD
+
 
 class OverwritingBuilder(AbstractARMv7Builder):
     def __init__(self, cb, start, size):
@@ -253,6 +258,7 @@
         self.cb.overwrite(self.index, char)
         self.index += 1
 
+
 class ARMv7Builder(BlockBuilderMixin, AbstractARMv7Builder):
     def __init__(self):
         AbstractARMv7Builder.__init__(self)
@@ -272,7 +278,7 @@
     # XXX remove and setup aligning in llsupport
     def materialize(self, asmmemmgr, allblocks, gcrootmap=None):
         size = self.get_relative_pos()
-        malloced = asmmemmgr.malloc(size, size+7)
+        malloced = asmmemmgr.malloc(size, size + 7)
         allblocks.append(malloced)
         rawstart = malloced[0]
         while(rawstart % FUNC_ALIGN != 0):
@@ -284,8 +290,16 @@
                 gcrootmap.put(rawstart + pos, mark)
         return rawstart
 
+    def clear_cache(self, addr):
+        if we_are_translated():
+            startaddr = rffi.cast(llmemory.Address, addr)
+            endaddr = rffi.cast(llmemory.Address,
+                            addr + self.get_relative_pos())
+            clear_cache(startaddr, endaddr)
+
     def copy_to_raw_memory(self, addr):
         self._copy_to_raw_memory(addr)
+        self.clear_cache(addr)
         self._dump(addr, "jit-backend-dump", 'arm')
 
     def currpos(self):
diff --git a/pypy/jit/backend/arm/conditions.py b/pypy/jit/backend/arm/conditions.py
--- a/pypy/jit/backend/arm/conditions.py
+++ b/pypy/jit/backend/arm/conditions.py
@@ -15,10 +15,12 @@
 AL = 0xE
 
 opposites = [NE, EQ, CC, CS, PL, MI, VC, VS, LS, HI, LT, GE, LE, GT, AL]
+
+
 def get_opposite_of(operation):
     return opposites[operation]
 
-# see mapping for floating poin according to 
+# see mapping for floating poin according to
 # http://blogs.arm.com/software-enablement/405-condition-codes-4-floating-point-comparisons-using-vfp/
 VFP_LT = CC
 VFP_LE = LS
diff --git a/pypy/jit/backend/arm/helper/assembler.py b/pypy/jit/backend/arm/helper/assembler.py
--- a/pypy/jit/backend/arm/helper/assembler.py
+++ b/pypy/jit/backend/arm/helper/assembler.py
@@ -29,7 +29,7 @@
         guard_opnum = guard.getopnum()
         if guard_opnum == rop.GUARD_FALSE:
             cond = false_cond
-        return self._emit_guard(guard, arglocs[1:], cond)
+        return self._emit_guard(guard, arglocs[1:], cond, save_exc=False)
     f.__name__ = 'emit_guard_%s' % name
     return f
 
@@ -92,7 +92,7 @@
         cond = true_cond
         if guard_opnum == rop.GUARD_FALSE:
             cond = false_cond
-        return self._emit_guard(guard, arglocs[2:], cond)
+        return self._emit_guard(guard, arglocs[2:], cond, save_exc=False)
     f.__name__ = 'emit_guard_%s' % name
     return f
 
@@ -137,7 +137,7 @@
         guard_opnum = guard.getopnum()
         if guard_opnum == rop.GUARD_FALSE:
             cond = false_cond
-        return self._emit_guard(guard, arglocs[2:], cond)
+        return self._emit_guard(guard, arglocs[2:], cond, save_exc=False)
     f.__name__ = 'emit_guard_%s' % name
     return f
 
diff --git a/pypy/jit/backend/arm/helper/regalloc.py b/pypy/jit/backend/arm/helper/regalloc.py
--- a/pypy/jit/backend/arm/helper/regalloc.py
+++ b/pypy/jit/backend/arm/helper/regalloc.py
@@ -3,42 +3,46 @@
 from pypy.jit.backend.arm.codebuilder import AbstractARMv7Builder
 from pypy.jit.metainterp.history import ConstInt, BoxInt, Box, FLOAT
 from pypy.jit.metainterp.history import ConstInt
+from pypy.rlib.objectmodel import we_are_translated
 
-# XXX create a version that does not need a ConstInt
-def _check_imm_arg(arg, size=0xFF, allow_zero=True):
+def check_imm_arg(arg, size=0xFF, allow_zero=True):
+    assert not isinstance(arg, ConstInt)
+    if not we_are_translated():
+        if not isinstance(arg, int):
+            import pdb; pdb.set_trace()
+    i = arg
+    if allow_zero:
+        lower_bound = i >= 0
+    else:
+        lower_bound = i > 0
+    return i <= size and lower_bound
+
+def check_imm_box(arg, size=0xFF, allow_zero=True):
     if isinstance(arg, ConstInt):
-        i = arg.getint()
-        if allow_zero:
-            lower_bound = i >= 0
-        else:
-            lower_bound = i > 0
-        return i <= size and lower_bound
+        return check_imm_arg(arg.getint(), size, allow_zero)
     return False
 
+
 def prepare_op_ri(name=None, imm_size=0xFF, commutative=True, allow_zero=True):
     def f(self, op, fcond):
         assert fcond is not None
         a0 = op.getarg(0)
         a1 = op.getarg(1)
         boxes = list(op.getarglist())
-        imm_a0 = _check_imm_arg(a0, imm_size, allow_zero=allow_zero)
-        imm_a1 = _check_imm_arg(a1, imm_size, allow_zero=allow_zero)
+        imm_a0 = check_imm_box(a0, imm_size, allow_zero=allow_zero)
+        imm_a1 = check_imm_box(a1, imm_size, allow_zero=allow_zero)
         if not imm_a0 and imm_a1:
-            l0, box = self._ensure_value_is_boxed(a0)
-            boxes.append(box)
+            l0 = self._ensure_value_is_boxed(a0)
             l1 = self.make_sure_var_in_reg(a1, boxes)
         elif commutative and imm_a0 and not imm_a1:
             l1 = self.make_sure_var_in_reg(a0, boxes)
-            l0, box = self._ensure_value_is_boxed(a1, boxes)
-            boxes.append(box)
+            l0 = self._ensure_value_is_boxed(a1, boxes)
         else:
-            l0, box = self._ensure_value_is_boxed(a0, boxes)
-            boxes.append(box)
-            l1, box = self._ensure_value_is_boxed(a1, boxes)
-            boxes.append(box)
-        self.possibly_free_vars(boxes)
+            l0 = self._ensure_value_is_boxed(a0, boxes)
+            l1 = self._ensure_value_is_boxed(a1, boxes)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.force_allocate_reg(op.result, boxes)
-        self.possibly_free_var(op.result)
         return [l0, l1, res]
     if name:
         f.__name__ = name
@@ -48,36 +52,33 @@
     if guard:
         def f(self, op, guard_op, fcond):
             locs = []
-            loc1, box1 = self._ensure_value_is_boxed(op.getarg(0))
+            loc1 = self._ensure_value_is_boxed(op.getarg(0))
             locs.append(loc1)
             if base:
-                loc2, box2 = self._ensure_value_is_boxed(op.getarg(1))
+                loc2 = self._ensure_value_is_boxed(op.getarg(1))
                 locs.append(loc2)
-                self.possibly_free_var(box2)
-            self.possibly_free_var(box1)
+            self.possibly_free_vars_for_op(op)
+            self.free_temp_vars()
             if guard_op is None:
                 res = self.force_allocate_reg(op.result)
                 assert float_result == (op.result.type == FLOAT)
-                self.possibly_free_var(op.result)
                 locs.append(res)
                 return locs
             else:
                 args = self._prepare_guard(guard_op, locs)
-                self.possibly_free_vars(guard_op.getfailargs())
                 return args
     else:
         def f(self, op, fcond):
             locs = []
-            loc1, box1 = self._ensure_value_is_boxed(op.getarg(0))
+            loc1 = self._ensure_value_is_boxed(op.getarg(0))
             locs.append(loc1)
             if base:
-                loc2, box2 = self._ensure_value_is_boxed(op.getarg(1))
+                loc2 = self._ensure_value_is_boxed(op.getarg(1))
                 locs.append(loc2)
-                self.possibly_free_var(box2)
-            self.possibly_free_var(box1)
+            self.possibly_free_vars_for_op(op)
+            self.free_temp_vars()
             res = self.force_allocate_reg(op.result)
             assert float_result == (op.result.type == FLOAT)
-            self.possibly_free_var(op.result)
             locs.append(res)
             return locs
     if name:
@@ -108,23 +109,21 @@
         assert fcond is not None
         boxes = list(op.getarglist())
         arg0, arg1 = boxes
-        imm_a1 = _check_imm_arg(arg1)
+        imm_a1 = check_imm_box(arg1)
 
-        l0, box = self._ensure_value_is_boxed(arg0, forbidden_vars=boxes)
-        boxes.append(box)
+        l0 = self._ensure_value_is_boxed(arg0, forbidden_vars=boxes)
         if imm_a1:
             l1 = self.make_sure_var_in_reg(arg1, boxes)
         else:
-            l1, box = self._ensure_value_is_boxed(arg1, forbidden_vars=boxes)
-            boxes.append(box)
-        self.possibly_free_vars(boxes)
+            l1 = self._ensure_value_is_boxed(arg1, forbidden_vars=boxes)
+
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         if guard_op is None:
             res = self.force_allocate_reg(op.result)
-            self.possibly_free_var(op.result)
             return [l0, l1, res]
         else:
             args = self._prepare_guard(guard_op, [l0, l1])
-            self.possibly_free_vars(guard_op.getfailargs())
             return args
     if name:
         f.__name__ = name
@@ -134,15 +133,14 @@
     def f(self, op, guard_op, fcond):
         assert fcond is not None
         a0 = op.getarg(0)
-        reg, box = self._ensure_value_is_boxed(a0)
+        assert isinstance(a0, Box)
+        reg = self.make_sure_var_in_reg(a0)
+        self.possibly_free_vars_for_op(op)
         if guard_op is None:
-            res = self.force_allocate_reg(op.result, [box])
-            self.possibly_free_vars([a0, box, op.result])
+            res = self.force_allocate_reg(op.result, [a0])
             return [reg, res]
         else:
-            args = self._prepare_guard(guard_op, [reg])
-            self.possibly_free_vars(guard_op.getfailargs())
-            return args
+            return self._prepare_guard(guard_op, [reg])
     if name:
         f.__name__ = name
     return f
diff --git a/pypy/jit/backend/arm/instruction_builder.py b/pypy/jit/backend/arm/instruction_builder.py
--- a/pypy/jit/backend/arm/instruction_builder.py
+++ b/pypy/jit/backend/arm/instruction_builder.py
@@ -1,5 +1,7 @@
 from pypy.jit.backend.arm import conditions as cond
 from pypy.jit.backend.arm import instructions
+
+
 # move table lookup out of generated functions
 def define_load_store_func(name, table):
     n = (0x1 << 26
@@ -13,6 +15,7 @@
     rncond = ('rn' in table and table['rn'] == '!0xF')
     if table['imm']:
         assert not b_zero
+
         def f(self, rt, rn, imm=0, cond=cond.AL):
             assert not (rncond and rn == 0xF)
             p = 1
@@ -20,7 +23,7 @@
             u, imm = self._encode_imm(imm)
             instr = (n
                     | cond << 28
-                    | (p & 0x1) <<  24
+                    | (p & 0x1) << 24
                     | (u & 0x1) << 23
                     | (w & 0x1) << 21
                     | imm_operation(rt, rn, imm))
@@ -34,7 +37,7 @@
             u, imm = self._encode_imm(imm)
             instr = (n
                     | cond << 28
-                    | (p & 0x1) <<  24
+                    | (p & 0x1) << 24
                     | (u & 0x1) << 23
                     | (w & 0x1) << 21
                     | reg_operation(rt, rn, rm, imm, s, shifttype))
@@ -44,6 +47,7 @@
             self.write32(instr)
     return f
 
+
 def define_extra_load_store_func(name, table):
     def check_registers(r1, r2):
         assert r1 % 2 == 0
@@ -57,7 +61,7 @@
     p = 1
     w = 0
     rncond = ('rn' in table and table['rn'] == '!0xF')
-    dual =  (name[-4] == 'D')
+    dual = (name[-4] == 'D')
 
     if dual:
         if name[-2:] == 'rr':
@@ -114,6 +118,7 @@
                         | (imm & 0xF))
     return f
 
+
 def define_data_proc_imm_func(name, table):
     n = (0x1 << 25
         | (table['op'] & 0x1F) << 20)
@@ -139,6 +144,7 @@
                 | imm_operation(0, rn, imm))
     return imm_func
 
+
 def define_data_proc_func(name, table):
     n = ((table['op1'] & 0x1F) << 20
         | (table['op2'] & 0x1F) << 7
@@ -175,6 +181,7 @@
                         | reg_operation(rd, rn, rm, imm, s, shifttype))
     return f
 
+
 def define_data_proc_reg_shift_reg_func(name, table):
     n = ((0x1 << 4) | (table['op1'] & 0x1F) << 20 | (table['op2'] & 0x3) << 5)
     if 'result' in table and not table['result']:
@@ -211,8 +218,10 @@
                         | (rn & 0xF))
     return f
 
+
 def define_supervisor_and_coproc_func(name, table):
     n = (0x3 << 26 | (table['op1'] & 0x3F) << 20 | (table['op'] & 0x1) << 4)
+
     def f(self, coproc, opc1, rt, crn, crm, opc2=0, cond=cond.AL):
         self.write32(n
                     | cond << 28
@@ -224,6 +233,7 @@
                     | (crm & 0xF))
     return f
 
+
 def define_multiply_func(name, table):
     n = (table['op'] & 0xF) << 20 | 0x9 << 4
     if 'acc' in table and table['acc']:
@@ -246,14 +256,14 @@
                             | (rn & 0xF))
 
     elif 'long' in table and table['long']:
-       def f(self, rdlo, rdhi, rn, rm, cond=cond.AL):
+        def f(self, rdlo, rdhi, rn, rm, cond=cond.AL):
             assert rdhi != rdlo
             self.write32(n
-                        | cond << 28
-                        | (rdhi & 0xF) << 16
-                        | (rdlo & 0xF) << 12
-                        | (rm & 0xF) << 8
-                        | (rn & 0xF))
+                    | cond << 28
+                    | (rdhi & 0xF) << 16
+                    | (rdlo & 0xF) << 12
+                    | (rm & 0xF) << 8
+                    | (rn & 0xF))
     else:
         def f(self, rd, rn, rm, cond=cond.AL, s=0):
             self.write32(n
@@ -265,8 +275,10 @@
 
     return f
 
+
 def define_block_data_func(name, table):
     n = (table['op'] & 0x3F) << 20
+
     def f(self, rn, regs, w=0, cond=cond.AL):
         # no R bit for now at bit 15
         instr = (n
@@ -278,6 +290,8 @@
         self.write32(instr)
 
     return f
+
+
 def define_float_load_store_func(name, table):
     n = (0x3 << 26
         | (table['opcode'] & 0x1F) << 20
@@ -288,9 +302,9 @@
     # the value actually encoded is imm / 4
     def f(self, dd, rn, imm=0, cond=cond.AL):
         assert imm % 4 == 0
-        imm = imm/4
+        imm = imm / 4
         u, imm = self._encode_imm(imm)
-        instr = ( n
+        instr = (n
                 | (cond & 0xF) << 28
                 | (u & 0x1) << 23
                 | (rn & 0xF) << 16
@@ -299,10 +313,11 @@
         self.write32(instr)
     return f
 
+
 def define_float64_data_proc_instructions_func(name, table):
     n = (0xE << 24
         | 0x5 << 9
-        | 0x1 << 8 # 64 bit flag
+        | 0x1 << 8  # 64 bit flag
         | (table['opc3'] & 0x3) << 6)
 
     if 'opc1' in table:
@@ -335,11 +350,13 @@
             self.write32(instr)
     return f
 
+
 def imm_operation(rt, rn, imm):
     return ((rn & 0xFF) << 16
     | (rt & 0xFF) << 12
     | (imm & 0xFFF))
 
+
 def reg_operation(rt, rn, rm, imm, s, shifttype):
     return ((s & 0x1) << 20
             | (rn & 0xF) << 16
@@ -348,10 +365,12 @@
             | (shifttype & 0x3) << 5
             | (rm & 0xF))
 
+
 def define_instruction(builder, key, val, target):
     f = builder(key, val)
     setattr(target, key, f)
 
+
 def define_instructions(target):
     inss = [k for k in instructions.__dict__.keys() if not k.startswith('__')]
     for name in inss:
diff --git a/pypy/jit/backend/arm/instructions.py b/pypy/jit/backend/arm/instructions.py
--- a/pypy/jit/backend/arm/instructions.py
+++ b/pypy/jit/backend/arm/instructions.py
@@ -1,93 +1,94 @@
 load_store = {
-    'STR_ri': {'A':0, 'op1': 0x0, 'op1not': 0x2, 'imm': True},
-    'STR_rr': {'A':1, 'op1': 0x0, 'op1not': 0x2, 'B': 0, 'imm': False},
-    'LDR_ri': {'A':0, 'op1': 0x1, 'op1not': 0x3, 'imm': True},
-    'LDR_rr': {'A':1, 'op1': 0x1, 'op1not': 0x3, 'B': 0, 'imm': False},
-    'STRB_ri': {'A':0, 'op1': 0x4, 'op1not': 0x6, 'rn':'!0xF', 'imm': True},
-    'STRB_rr': {'A':1, 'op1': 0x4, 'op1not': 0x6, 'B': 0, 'imm': False},
-    'LDRB_ri': {'A':0, 'op1': 0x5, 'op1not': 0x7, 'rn':'!0xF', 'imm': True},
-    'LDRB_rr': {'A':1, 'op1': 0x5, 'op1not': 0x7, 'B': 0, 'imm': False},
+    'STR_ri': {'A': 0, 'op1': 0x0, 'op1not': 0x2, 'imm': True},
+    'STR_rr': {'A': 1, 'op1': 0x0, 'op1not': 0x2, 'B': 0, 'imm': False},
+    'LDR_ri': {'A': 0, 'op1': 0x1, 'op1not': 0x3, 'imm': True},
+    'LDR_rr': {'A': 1, 'op1': 0x1, 'op1not': 0x3, 'B': 0, 'imm': False},
+    'STRB_ri': {'A': 0, 'op1': 0x4, 'op1not': 0x6, 'rn': '!0xF', 'imm': True},
+    'STRB_rr': {'A': 1, 'op1': 0x4, 'op1not': 0x6, 'B': 0, 'imm': False},
+    'LDRB_ri': {'A': 0, 'op1': 0x5, 'op1not': 0x7, 'rn': '!0xF', 'imm': True},
+    'LDRB_rr': {'A': 1, 'op1': 0x5, 'op1not': 0x7, 'B': 0, 'imm': False},
 }
-extra_load_store = { #Section 5.2.8
+extra_load_store = {  # Section 5.2.8
     'STRH_rr':  {'op2': 0x1, 'op1': 0x0},
     'LDRH_rr':  {'op2': 0x1, 'op1': 0x1},
     'STRH_ri':  {'op2': 0x1, 'op1': 0x4},
-    'LDRH_ri':  {'op2': 0x1, 'op1': 0x5, 'rn':'!0xF'},
+    'LDRH_ri':  {'op2': 0x1, 'op1': 0x5, 'rn': '!0xF'},
     'LDRD_rr':  {'op2': 0x2, 'op1': 0x0},
     'LDRSB_rr': {'op2': 0x2, 'op1': 0x1},
     'LDRD_ri':  {'op2': 0x2, 'op1': 0x4},
-    'LDRSB_ri': {'op2': 0x2, 'op1': 0x5, 'rn':'!0xF'},
+    'LDRSB_ri': {'op2': 0x2, 'op1': 0x5, 'rn': '!0xF'},
     'STRD_rr':  {'op2': 0x3, 'op1': 0x0},
     'LDRSH_rr': {'op2': 0x3, 'op1': 0x1},
     'STRD_ri':  {'op2': 0x3, 'op1': 0x4},
-    'LDRSH_ri': {'op2': 0x3, 'op1': 0x5, 'rn':'!0xF'},
+    'LDRSH_ri': {'op2': 0x3, 'op1': 0x5, 'rn': '!0xF'},
 }
 
 
 data_proc = {
-    'AND_rr': {'op1':0x0, 'op2':0, 'op3':0, 'result':True, 'base':True},
-    'EOR_rr': {'op1':0x2, 'op2':0, 'op3':0, 'result':True, 'base':True},
-    'SUB_rr': {'op1':0x4, 'op2':0, 'op3':0, 'result':True, 'base':True},
-    'RSB_rr': {'op1':0x6, 'op2':0, 'op3':0, 'result':True, 'base':True},
-    'ADD_rr': {'op1':0x8, 'op2':0, 'op3':0, 'result':True, 'base':True},
-    'ADC_rr': {'op1':0xA, 'op2':0, 'op3':0, 'result':True, 'base':True},
-    'SBC_rr': {'op1':0xC, 'op2':0, 'op3':0, 'result':True, 'base':True},
-    'RSC_rr': {'op1':0xE, 'op2':0, 'op3':0, 'result':True, 'base':True},
-    'TST_rr': {'op1':0x11, 'op2':0, 'op3':0, 'result':False, 'base':True},
-    'TEQ_rr': {'op1':0x13, 'op2':0, 'op3':0, 'result':False, 'base':True},
-    'CMP_rr': {'op1':0x15, 'op2':0, 'op3':0, 'result':False, 'base':True},
-    'CMN_rr': {'op1':0x17, 'op2':0, 'op3':0, 'result':False, 'base':True},
-    'ORR_rr': {'op1':0x18, 'op2':0, 'op3':0, 'result':True, 'base':True},
-    'MOV_rr': {'op1':0x1A, 'op2':0, 'op3':0, 'result':True, 'base':False},
-    'LSL_ri': {'op1':0x1A, 'op2':0x0, 'op3':0, 'op2cond':'!0', 'result':False, 'base':True},
-    'LSR_ri': {'op1':0x1A, 'op2':0, 'op3':0x1, 'op2cond':'', 'result':False, 'base':True},
-    'ASR_ri': {'op1':0x1A, 'op2':0, 'op3':0x2, 'op2cond':'', 'result':False, 'base':True},
-    #'RRX_ri': {'op1':0x1A, 'op2':0, 'op3':0x3, 'op2cond':'0', 'result':False, 'base':True},
-    'ROR_ri': {'op1':0x1A, 'op2':0x0, 'op3':0x3, 'op2cond':'!0', 'result':True, 'base':False},
-    #BIC
-    'MVN_rr': {'op1':0x1E, 'op2':0x0, 'op3':0x0, 'result':True, 'base':False},
+    'AND_rr': {'op1': 0x0, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+    'EOR_rr': {'op1': 0x2, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+    'SUB_rr': {'op1': 0x4, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+    'RSB_rr': {'op1': 0x6, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+    'ADD_rr': {'op1': 0x8, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+    'ADC_rr': {'op1': 0xA, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+    'SBC_rr': {'op1': 0xC, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+    'RSC_rr': {'op1': 0xE, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+    'TST_rr': {'op1': 0x11, 'op2': 0, 'op3': 0, 'result': False, 'base': True},
+    'TEQ_rr': {'op1': 0x13, 'op2': 0, 'op3': 0, 'result': False, 'base': True},
+    'CMP_rr': {'op1': 0x15, 'op2': 0, 'op3': 0, 'result': False, 'base': True},
+    'CMN_rr': {'op1': 0x17, 'op2': 0, 'op3': 0, 'result': False, 'base': True},
+    'ORR_rr': {'op1': 0x18, 'op2': 0, 'op3': 0, 'result': True, 'base': True},
+    'MOV_rr': {'op1': 0x1A, 'op2': 0, 'op3': 0, 'result': True, 'base': False},
+    'LSL_ri': {'op1': 0x1A, 'op2': 0x0, 'op3': 0, 'op2cond': '!0',
+                                                'result': False, 'base': True},
+    'LSR_ri': {'op1': 0x1A, 'op2': 0, 'op3': 0x1, 'op2cond': '',
+                                                'result': False, 'base': True},
+    'ASR_ri': {'op1': 0x1A, 'op2': 0, 'op3': 0x2, 'op2cond': '',
+                                                'result': False, 'base': True},
+    'ROR_ri': {'op1': 0x1A, 'op2': 0x0, 'op3': 0x3, 'op2cond': '!0',
+                                                'result': True, 'base': False},
+    'MVN_rr': {'op1': 0x1E, 'op2': 0x0, 'op3': 0x0, 'result': True,
+                                                                'base': False},
 
 }
 
 data_proc_reg_shift_reg = {
-    'AND_rr_sr': {'op1':0x0,  'op2':0},
-    'EOR_rr_sr': {'op1':0x2,  'op2':0},
-    'SUB_rr_sr': {'op1':0x4,  'op2':0},
-    'RSB_rr_sr': {'op1':0x6,  'op2':0},
-    'ADD_rr_sr': {'op1':0x8,  'op2':0},
-    'ADC_rr_sr': {'op1':0xA,  'op2':0},
-    'SBC_rr_sr': {'op1':0xC,  'op2':0},
-    'RSC_rr_sr': {'op1':0xE,  'op2':0},
-    'TST_rr_sr': {'op1':0x11, 'op2':0, 'result': False},
-    'TEQ_rr_sr': {'op1':0x13, 'op2':0, 'result': False},
-    'CMP_rr_sr': {'op1':0x15, 'op2':0, 'result': False},
-    'CMN_rr_sr': {'op1':0x17, 'op2':0, 'result': False},
-    'ORR_rr_sr': {'op1':0x18, 'op2':0},
-    'LSL_rr': {'op1':0x1A, 'op2':0, },
-    'LSR_rr': {'op1':0x1A, 'op2':0x1},
-    'ASR_rr': {'op1':0x1A, 'op2':0x2},
-    #'RRX_rr': {'op1':0x1A, 'op2':0,},
-    'ROR_rr': {'op1':0x1A, 'op2':0x3},
-    # BIC, MVN
+    'AND_rr_sr': {'op1': 0x0,  'op2': 0},
+    'EOR_rr_sr': {'op1': 0x2,  'op2': 0},
+    'SUB_rr_sr': {'op1': 0x4,  'op2': 0},
+    'RSB_rr_sr': {'op1': 0x6,  'op2': 0},
+    'ADD_rr_sr': {'op1': 0x8,  'op2': 0},
+    'ADC_rr_sr': {'op1': 0xA,  'op2': 0},
+    'SBC_rr_sr': {'op1': 0xC,  'op2': 0},
+    'RSC_rr_sr': {'op1': 0xE,  'op2': 0},
+    'TST_rr_sr': {'op1': 0x11, 'op2': 0, 'result': False},
+    'TEQ_rr_sr': {'op1': 0x13, 'op2': 0, 'result': False},
+    'CMP_rr_sr': {'op1': 0x15, 'op2': 0, 'result': False},
+    'CMN_rr_sr': {'op1': 0x17, 'op2': 0, 'result': False},
+    'ORR_rr_sr': {'op1': 0x18, 'op2': 0},
+    'LSL_rr': {'op1': 0x1A, 'op2': 0, },
+    'LSR_rr': {'op1': 0x1A, 'op2': 0x1},
+    'ASR_rr': {'op1': 0x1A, 'op2': 0x2},
+    'ROR_rr': {'op1': 0x1A, 'op2': 0x3},
 }
 
 data_proc_imm = {
-    'AND_ri': {'op': 0, 'result':True, 'base':True},
-    'EOR_ri': {'op': 0x2, 'result':True, 'base':True},
-    'SUB_ri': {'op': 0x4, 'result':True, 'base':True},
-    'RSB_ri': {'op': 0x6, 'result':True, 'base':True},
-    'ADD_ri': {'op': 0x8, 'result':True, 'base':True},
-    'ADC_ri': {'op': 0xA, 'result':True, 'base':True},
-    'SBC_ri': {'op': 0xC, 'result':True, 'base':True},
-    'RSC_ri': {'op': 0xE, 'result':True, 'base':True},
-    'TST_ri': {'op': 0x11, 'result':False, 'base':True},
-    'TEQ_ri': {'op': 0x13, 'result':False, 'base':True},
-    'CMP_ri': {'op': 0x15, 'result':False, 'base':True},
-    'CMN_ri': {'op': 0x17, 'result':False, 'base':True},
-    'ORR_ri': {'op': 0x18, 'result':True, 'base':True},
-    'MOV_ri': {'op': 0x1A, 'result':True, 'base':False},
-    'BIC_ri': {'op': 0x1C, 'result':True, 'base':True},
-    'MVN_ri': {'op': 0x1E, 'result':True, 'base':False},
+    'AND_ri': {'op': 0, 'result': True, 'base': True},
+    'EOR_ri': {'op': 0x2, 'result': True, 'base': True},
+    'SUB_ri': {'op': 0x4, 'result': True, 'base': True},
+    'RSB_ri': {'op': 0x6, 'result': True, 'base': True},
+    'ADD_ri': {'op': 0x8, 'result': True, 'base': True},
+    'ADC_ri': {'op': 0xA, 'result': True, 'base': True},
+    'SBC_ri': {'op': 0xC, 'result': True, 'base': True},
+    'RSC_ri': {'op': 0xE, 'result': True, 'base': True},
+    'TST_ri': {'op': 0x11, 'result': False, 'base': True},
+    'TEQ_ri': {'op': 0x13, 'result': False, 'base': True},
+    'CMP_ri': {'op': 0x15, 'result': False, 'base': True},
+    'CMN_ri': {'op': 0x17, 'result': False, 'base': True},
+    'ORR_ri': {'op': 0x18, 'result': True, 'base': True},
+    'MOV_ri': {'op': 0x1A, 'result': True, 'base': False},
+    'BIC_ri': {'op': 0x1C, 'result': True, 'base': True},
+    'MVN_ri': {'op': 0x1E, 'result': True, 'base': False},
 }
 
 supervisor_and_coproc = {
diff --git a/pypy/jit/backend/arm/jump.py b/pypy/jit/backend/arm/jump.py
--- a/pypy/jit/backend/arm/jump.py
+++ b/pypy/jit/backend/arm/jump.py
@@ -1,7 +1,6 @@
 # ../x86/jump.py
 # XXX combine with ../x86/jump.py and move to llsupport
-import sys
-from pypy.tool.pairtype import extendabletype
+
 
 def remap_frame_layout(assembler, src_locations, dst_locations, tmpreg):
     pending_dests = len(dst_locations)
@@ -18,7 +17,10 @@
         key = src.as_key()
         if key in srccount:
             if key == dst_locations[i].as_key():
-                srccount[key] = -sys.maxint     # ignore a move "x = x"
+                # ignore a move "x = x"
+                # setting any "large enough" negative value is ok, but
+                # be careful of overflows, don't use -sys.maxint
+                srccount[key] = -len(dst_locations) - 1
                 pending_dests -= 1
             else:
                 srccount[key] += 1
@@ -65,12 +67,14 @@
                     assembler.regalloc_pop(dst)
             assert pending_dests == 0
 
+
 def _move(assembler, src, dst, tmpreg):
     if dst.is_stack() and src.is_stack():
         assembler.regalloc_mov(src, tmpreg)
         src = tmpreg
     assembler.regalloc_mov(src, dst)
 
+
 def remap_frame_layout_mixed(assembler,
                              src_locations1, dst_locations1, tmpreg1,
                              src_locations2, dst_locations2, tmpreg2):
@@ -84,7 +88,7 @@
     src_locations2red = []
     dst_locations2red = []
     for i in range(len(src_locations2)):
-        loc    = src_locations2[i]
+        loc = src_locations2[i]
         dstloc = dst_locations2[i]
         if loc.is_stack():
             key = loc.as_key()
diff --git a/pypy/jit/backend/arm/locations.py b/pypy/jit/backend/arm/locations.py
--- a/pypy/jit/backend/arm/locations.py
+++ b/pypy/jit/backend/arm/locations.py
@@ -1,5 +1,7 @@
-from pypy.jit.metainterp.history import INT, FLOAT, REF
+from pypy.jit.metainterp.history import INT, FLOAT
 from pypy.jit.backend.arm.arch import WORD
+
+
 class AssemblerLocation(object):
     _immutable_ = True
     type = INT
@@ -22,6 +24,7 @@
     def as_key(self):
         raise NotImplementedError
 
+
 class RegisterLocation(AssemblerLocation):
     _immutable_ = True
     width = WORD
@@ -38,13 +41,15 @@
     def as_key(self):
         return self.value
 
+
 class VFPRegisterLocation(RegisterLocation):
     _immutable_ = True
-    type = FLOAT 
-    width = 2*WORD
+    type = FLOAT
+    width = 2 * WORD
 
     def get_single_precision_regs(self):
-        return [VFPRegisterLocation(i) for i in [self.value*2, self.value*2+1]]
+        return [VFPRegisterLocation(i) for i in
+                        [self.value * 2, self.value * 2 + 1]]
 
     def __repr__(self):
         return 'vfp%d' % self.value
@@ -58,11 +63,11 @@
     def as_key(self):
         return self.value + 20
 
+
 class ImmLocation(AssemblerLocation):
     _immutable_ = True
     width = WORD
 
-
     def __init__(self, value):
         self.value = value
 
@@ -78,11 +83,12 @@
     def as_key(self):
         return self.value + 40
 
+
 class ConstFloatLoc(AssemblerLocation):
     """This class represents an imm float value which is stored in memory at
     the address stored in the field value"""
     _immutable_ = True
-    width = 2*WORD
+    width = 2 * WORD
     type = FLOAT
 
     def __init__(self, value):
@@ -100,6 +106,7 @@
     def as_key(self):
         return -1 * self.value
 
+
 class StackLocation(AssemblerLocation):
     _immutable_ = True
 
@@ -123,5 +130,6 @@
     def as_key(self):
         return -self.position
 
+
 def imm(i):
     return ImmLocation(i)
diff --git a/pypy/jit/backend/arm/opassembler.py b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -1,51 +1,48 @@
 from __future__ import with_statement
 from pypy.jit.backend.arm import conditions as c
-from pypy.jit.backend.arm import locations
 from pypy.jit.backend.arm import registers as r
 from pypy.jit.backend.arm import shift
-from pypy.jit.backend.arm.arch import (WORD, FUNC_ALIGN, arm_int_div,
-                                        arm_int_div_sign, arm_int_mod_sign,
-                                        arm_int_mod, PC_OFFSET)
+from pypy.jit.backend.arm.arch import WORD, PC_OFFSET
 
 from pypy.jit.backend.arm.helper.assembler import (gen_emit_op_by_helper_call,
-                                                    gen_emit_op_unary_cmp,
-                                                    gen_emit_guard_unary_cmp,
-                                                    gen_emit_op_ri,
-                                                    gen_emit_cmp_op,
-                                                    gen_emit_cmp_op_guard,
-                                                    gen_emit_float_op,
-                                                    gen_emit_float_cmp_op,
-                                                    gen_emit_float_cmp_op_guard,
-                                                    gen_emit_unary_float_op, 
-                                                    saved_registers,
-                                                    count_reg_args)
+                                                gen_emit_op_unary_cmp,
+                                                gen_emit_guard_unary_cmp,
+                                                gen_emit_op_ri,
+                                                gen_emit_cmp_op,
+                                                gen_emit_cmp_op_guard,
+                                                gen_emit_float_op,
+                                                gen_emit_float_cmp_op,
+                                                gen_emit_float_cmp_op_guard,
+                                                gen_emit_unary_float_op,
+                                                saved_registers,
+                                                count_reg_args)
 from pypy.jit.backend.arm.codebuilder import ARMv7Builder, OverwritingBuilder
 from pypy.jit.backend.arm.jump import remap_frame_layout
-from pypy.jit.backend.arm.regalloc import Regalloc, TempInt, TempPtr
+from pypy.jit.backend.arm.regalloc import TempInt, TempPtr
 from pypy.jit.backend.arm.locations import imm
 from pypy.jit.backend.llsupport import symbolic
-from pypy.jit.backend.llsupport.descr import BaseFieldDescr, BaseArrayDescr
-from pypy.jit.backend.llsupport.regalloc import compute_vars_longevity
-from pypy.jit.metainterp.history import (Const, ConstInt, BoxInt, Box,
-                                        AbstractFailDescr, LoopToken, INT, FLOAT, REF)
+from pypy.jit.metainterp.history import (Box, AbstractFailDescr,
+                                            INT, FLOAT, REF)
+from pypy.jit.metainterp.history import JitCellToken, TargetToken
 from pypy.jit.metainterp.resoperation import rop
-from pypy.rlib import rgc
 from pypy.rlib.objectmodel import we_are_translated
-from pypy.rpython.annlowlevel import llhelper
-from pypy.rpython.lltypesystem import lltype, rffi, rstr, llmemory
+from pypy.rpython.lltypesystem import lltype, rffi, rstr
 
 NO_FORCE_INDEX = -1
 
+
 class GuardToken(object):
-    def __init__(self, descr, failargs, faillocs, offset, fcond=c.AL,
-                                        save_exc=False, is_invalidate=False):
+    def __init__(self, descr, failargs, faillocs, offset,
+                            save_exc, fcond=c.AL, is_invalidate=False):
+        assert isinstance(save_exc, bool)
         self.descr = descr
         self.offset = offset
         self.is_invalidate = is_invalidate
         self.failargs = failargs
         self.faillocs = faillocs
         self.save_exc = save_exc
-        self.fcond=fcond
+        self.fcond = fcond
+
 
 class IntOpAsslember(object):
 
@@ -95,15 +92,17 @@
     def emit_guard_int_mul_ovf(self, op, guard, arglocs, regalloc, fcond):
         reg1 = arglocs[0]
         reg2 = arglocs[1]
-        res =  arglocs[2]
+        res = arglocs[2]
         failargs = arglocs[3:]
-        self.mc.SMULL(res.value, r.ip.value, reg1.value, reg2.value, cond=fcond)
-        self.mc.CMP_rr(r.ip.value, res.value, shifttype=shift.ASR, imm=31, cond=fcond)
+        self.mc.SMULL(res.value, r.ip.value, reg1.value, reg2.value,
+                                                                cond=fcond)
+        self.mc.CMP_rr(r.ip.value, res.value, shifttype=shift.ASR,
+                                                        imm=31, cond=fcond)
 
         if guard.getopnum() == rop.GUARD_OVERFLOW:
-            fcond = self._emit_guard(guard, failargs, c.NE)
+            fcond = self._emit_guard(guard, failargs, c.NE, save_exc=False)
         elif guard.getopnum() == rop.GUARD_NO_OVERFLOW:
-            fcond = self._emit_guard(guard, failargs, c.EQ)
+            fcond = self._emit_guard(guard, failargs, c.EQ, save_exc=False)
         else:
             assert 0
         return fcond
@@ -112,7 +111,7 @@
         self.emit_op_int_add(op, arglocs[0:3], regalloc, fcond, flags=True)
         self._emit_guard_overflow(guard, arglocs[3:], fcond)
         return fcond
-    
+
     def emit_guard_int_sub_ovf(self, op, guard, arglocs, regalloc, fcond):
         self.emit_op_int_sub(op, arglocs[0:3], regalloc, fcond, flags=True)
         self._emit_guard_overflow(guard, arglocs[3:], fcond)
@@ -136,8 +135,6 @@
     emit_op_int_gt = gen_emit_cmp_op('int_gt', c.GT)
     emit_op_int_ge = gen_emit_cmp_op('int_ge', c.GE)
 
-
-
     emit_guard_int_lt = gen_emit_cmp_op_guard('int_lt', c.LT)
     emit_guard_int_le = gen_emit_cmp_op_guard('int_le', c.LE)
     emit_guard_int_eq = gen_emit_cmp_op_guard('int_eq', c.EQ)
@@ -155,16 +152,15 @@
     emit_guard_uint_lt = gen_emit_cmp_op_guard('uint_lt', c.LO)
     emit_guard_uint_ge = gen_emit_cmp_op_guard('uint_ge', c.HS)
 
-    emit_op_ptr_eq = emit_op_int_eq
-    emit_op_ptr_ne = emit_op_int_ne
-    emit_guard_ptr_eq = emit_guard_int_eq
-    emit_guard_ptr_ne = emit_guard_int_ne
+    emit_op_ptr_eq = emit_op_instance_ptr_eq = emit_op_int_eq
+    emit_op_ptr_ne = emit_op_instance_ptr_ne = emit_op_int_ne
+    emit_guard_ptr_eq = emit_guard_instance_ptr_eq = emit_guard_int_eq
+    emit_guard_ptr_ne = emit_guard_instance_ptr_ne = emit_guard_int_ne
 
     emit_op_int_add_ovf = emit_op_int_add
     emit_op_int_sub_ovf = emit_op_int_sub
 
 
-
 class UnaryIntOpAssembler(object):
 
     _mixin_ = True
@@ -186,34 +182,44 @@
         self.mc.RSB_ri(resloc.value, l0.value, imm=0)
         return fcond
 
+
 class GuardOpAssembler(object):
 
     _mixin_ = True
 
-    def _emit_guard(self, op, arglocs, fcond, save_exc=False, is_guard_not_ivalidated=False):
+    def _emit_guard(self, op, arglocs, fcond, save_exc,
+                                    is_guard_not_invalidated=False):
+        assert isinstance(save_exc, bool)
+        assert isinstance(fcond, int)
         descr = op.getdescr()
         assert isinstance(descr, AbstractFailDescr)
 
-
         if not we_are_translated() and hasattr(op, 'getfailargs'):
-           print 'Failargs: ', op.getfailargs()
+            print 'Failargs: ', op.getfailargs()
 
         pos = self.mc.currpos()
-        self.mc.NOP()
+        # For all guards that are not GUARD_NOT_INVALIDATED we emit a
+        # breakpoint to ensure the location is patched correctly. In the case
+        # of GUARD_NOT_INVALIDATED we use just a NOP, because it is only
+        # eventually patched at a later point.
+        if is_guard_not_invalidated:
+            self.mc.NOP()
+        else:
+            self.mc.BKPT()
         self.pending_guards.append(GuardToken(descr,
                                     failargs=op.getfailargs(),
                                     faillocs=arglocs,
                                     offset=pos,
-                                    fcond=fcond,
-                                    is_invalidate=is_guard_not_ivalidated,
-                                    save_exc=save_exc))
+                                    save_exc=save_exc,
+                                    is_invalidate=is_guard_not_invalidated,
+                                    fcond=fcond))
         return c.AL
 
     def _emit_guard_overflow(self, guard, failargs, fcond):
         if guard.getopnum() == rop.GUARD_OVERFLOW:
-            fcond = self._emit_guard(guard, failargs, c.VS)
+            fcond = self._emit_guard(guard, failargs, c.VS, save_exc=False)
         elif guard.getopnum() == rop.GUARD_NO_OVERFLOW:
-            fcond = self._emit_guard(guard, failargs, c.VC)
+            fcond = self._emit_guard(guard, failargs, c.VC, save_exc=False)
         else:
             assert 0
         return fcond
@@ -222,14 +228,14 @@
         l0 = arglocs[0]
         failargs = arglocs[1:]
         self.mc.CMP_ri(l0.value, 0)
-        fcond = self._emit_guard(op, failargs, c.NE)
+        fcond = self._emit_guard(op, failargs, c.NE, save_exc=False)
         return fcond
 
     def emit_op_guard_false(self, op, arglocs, regalloc, fcond):
         l0 = arglocs[0]
         failargs = arglocs[1:]
         self.mc.CMP_ri(l0.value, 0)
-        fcond = self._emit_guard(op, failargs, c.EQ)
+        fcond = self._emit_guard(op, failargs, c.EQ, save_exc=False)
         return fcond
 
     def emit_op_guard_value(self, op, arglocs, regalloc, fcond):
@@ -246,17 +252,17 @@
             assert l1.is_vfp_reg()
             self.mc.VCMP(l0.value, l1.value)
             self.mc.VMRS(cond=fcond)
-        fcond = self._emit_guard(op, failargs, c.EQ)
+        fcond = self._emit_guard(op, failargs, c.EQ, save_exc=False)
         return fcond
 
     emit_op_guard_nonnull = emit_op_guard_true
     emit_op_guard_isnull = emit_op_guard_false
 
     def emit_op_guard_no_overflow(self, op, arglocs, regalloc, fcond):
-        return self._emit_guard(op, arglocs, c.VC)
+        return self._emit_guard(op, arglocs, c.VC, save_exc=False)
 
     def emit_op_guard_overflow(self, op, arglocs, regalloc, fcond):
-        return self._emit_guard(op, arglocs, c.VS)
+        return self._emit_guard(op, arglocs, c.VS, save_exc=False)
 
     # from ../x86/assembler.py:1265
     def emit_op_guard_class(self, op, arglocs, regalloc, fcond):
@@ -268,14 +274,15 @@
 
         self.mc.CMP_ri(arglocs[0].value, 0)
         if offset is not None:
-            self._emit_guard(op, arglocs[3:], c.NE)
+            self._emit_guard(op, arglocs[3:], c.NE, save_exc=False)
         else:
             raise NotImplementedError
         self._cmp_guard_class(op, arglocs, regalloc, fcond)
         return fcond
 
     def emit_op_guard_not_invalidated(self, op, locs, regalloc, fcond):
-        return self._emit_guard(op, locs, fcond, is_guard_not_ivalidated=True)
+        return self._emit_guard(op, locs, fcond, save_exc=False,
+                                            is_guard_not_invalidated=True)
 
     def _cmp_guard_class(self, op, locs, regalloc, fcond):
         offset = locs[2]
@@ -290,7 +297,7 @@
             raise NotImplementedError
             # XXX port from x86 backend once gc support is in place
 
-        return self._emit_guard(op, locs[3:], c.EQ)
+        return self._emit_guard(op, locs[3:], c.EQ, save_exc=False)
 
 
 class OpAssembler(object):
@@ -298,37 +305,86 @@
     _mixin_ = True
 
     def emit_op_jump(self, op, arglocs, regalloc, fcond):
+        # The backend's logic assumes that the target code is in a piece of
+        # assembler that was also called with the same number of arguments,
+        # so that the locations [ebp+8..] of the input arguments are valid
+        # stack locations both before and after the jump.
+        #
         descr = op.getdescr()
-        assert isinstance(descr, LoopToken)
+        assert isinstance(descr, TargetToken)
         assert fcond == c.AL
+        my_nbargs = self.current_clt._debug_nbargs
+        target_nbargs = descr._arm_clt._debug_nbargs
+        assert my_nbargs == target_nbargs
 
         self._insert_checks()
-        if descr._arm_bootstrap_code == 0:
+        if descr in self.target_tokens_currently_compiling:
             self.mc.B_offs(descr._arm_loop_code, fcond)
         else:
-            target = descr._arm_bootstrap_code + descr._arm_loop_code
-            self.mc.B(target, fcond)
-            new_fd = max(regalloc.frame_manager.frame_depth, descr._arm_frame_depth)
-            regalloc.frame_manager.frame_depth = new_fd
+            self.mc.B(descr._arm_loop_code, fcond)
         return fcond
 
     def emit_op_finish(self, op, arglocs, regalloc, fcond):
-        self._gen_path_to_exit_path(op.getdescr(), op.getarglist(), arglocs, c.AL)
+        for i in range(len(arglocs) - 1):
+            loc = arglocs[i]
+            box = op.getarg(i)
+            if loc is None:
+                continue
+            if loc.is_reg():
+                if box.type == REF:
+                    adr = self.fail_boxes_ptr.get_addr_for_num(i)
+                elif box.type == INT:
+                    adr = self.fail_boxes_int.get_addr_for_num(i)
+                else:
+                    assert 0
+                self.mc.gen_load_int(r.ip.value, adr)
+                self.mc.STR_ri(loc.value, r.ip.value)
+            elif loc.is_vfp_reg():
+                assert box.type == FLOAT
+                adr = self.fail_boxes_float.get_addr_for_num(i)
+                self.mc.gen_load_int(r.ip.value, adr)
+                self.mc.VSTR(loc.value, r.ip.value)
+            elif loc.is_stack() or loc.is_imm() or loc.is_imm_float():
+                if box.type == FLOAT:
+                    adr = self.fail_boxes_float.get_addr_for_num(i)
+                    self.mov_loc_loc(loc, r.vfp_ip)
+                    self.mc.gen_load_int(r.ip.value, adr)
+                    self.mc.VSTR(r.vfp_ip.value, r.ip.value)
+                elif box.type == REF or box.type == INT:
+                    if box.type == REF:
+                        adr = self.fail_boxes_ptr.get_addr_for_num(i)
+                    elif box.type == INT:
+                        adr = self.fail_boxes_int.get_addr_for_num(i)
+                    else:
+                        assert 0
+                    self.mov_loc_loc(loc, r.ip)
+                    self.mc.gen_load_int(r.lr.value, adr)
+                    self.mc.STR_ri(r.ip.value, r.lr.value)
+            else:
+                assert 0
+        # note: no exception should currently be set in llop.get_exception_addr
+        # even if this finish may be an exit_frame_with_exception (in this case
+        # the exception instance is in arglocs[0]).
+        addr = self.cpu.get_on_leave_jitted_int(save_exception=False)
+        self.mc.BL(addr)
+        self.mc.gen_load_int(r.r0.value, arglocs[-1].value)
+        self.gen_func_epilog()
         return fcond
 
-    def emit_op_call(self, op, args, regalloc, fcond, force_index=-1):
+    def emit_op_call(self, op, args, regalloc, fcond,
+                                force_index=NO_FORCE_INDEX):
         adr = args[0].value
         arglist = op.getarglist()[1:]
-        if force_index == -1:
+        if force_index == NO_FORCE_INDEX:
             force_index = self.write_new_force_index()
-        cond =  self._emit_call(force_index, adr, arglist, 
+        cond = self._emit_call(force_index, adr, arglist,
                                     regalloc, fcond, op.result)
         descr = op.getdescr()
         #XXX Hack, Hack, Hack
-        if op.result and not we_are_translated() and not isinstance(descr, LoopToken):
+        if (op.result and not we_are_translated()):
             #XXX check result type
             loc = regalloc.rm.call_result_location(op.result)
-            size = descr.get_result_size(False)
+            size = descr.get_result_size()
             signed = descr.is_result_signed()
             self._ensure_result_bit_extension(loc, size, signed)
         return cond
@@ -336,11 +392,12 @@
     # XXX improve this interface
     # emit_op_call_may_force
     # XXX improve freeing of stuff here
-    def _emit_call(self, force_index, adr, args, regalloc, fcond=c.AL, result=None):
+    # XXX add an interface that takes locations instead of boxes
+    def _emit_call(self, force_index, adr, args, regalloc, fcond=c.AL,
+                                                            result=None):
         n_args = len(args)
         reg_args = count_reg_args(args)
 
-
         # all arguments past the 4th go on the stack
         n = 0   # used to count the number of words pushed on the stack, so we
                 #can later modify the SP back to its original value
@@ -365,15 +422,15 @@
                 stack_args.append(None)
 
             #then we push every thing on the stack
-            for i in range(len(stack_args) -1, -1, -1):
+            for i in range(len(stack_args) - 1, -1, -1):
                 arg = stack_args[i]
                 if arg is None:
                     self.mc.PUSH([r.ip.value])
                 else:
                     self.regalloc_push(regalloc.loc(arg))
 
-        # collect variables that need to go in registers
-        # and the registers they will be stored in 
+        # collect variables that need to go in registers and the registers they
+        # will be stored in
         num = 0
         count = 0
         non_float_locs = []
@@ -405,7 +462,7 @@
         remap_frame_layout(self, non_float_locs, non_float_regs, r.ip)
 
         for loc, reg in float_locs:
-            self.mov_from_vfp_loc(loc, reg, r.all_regs[reg.value+1])
+            self.mov_from_vfp_loc(loc, reg, r.all_regs[reg.value + 1])
 
         #the actual call
         self.mc.BL(adr)
@@ -448,7 +505,7 @@
 
         self.mc.CMP_rr(r.ip.value, loc.value)
         self._emit_guard(op, failargs, c.EQ, save_exc=True)
-        self.mc.gen_load_int(loc.value, pos_exc_value.value, fcond)
+        self.mc.gen_load_int(loc.value, pos_exc_value.value)
         if resloc:
             self.mc.LDR_ri(resloc.value, loc.value)
         self.mc.MOV_ri(r.ip.value, 0)
@@ -494,7 +551,7 @@
         self.mc.TST_ri(r.ip.value, imm=ofs)
 
         jz_location = self.mc.currpos()
-        self.mc.NOP()
+        self.mc.BKPT()
 
         # the following is supposed to be the slow path, so whenever possible
         # we choose the most compact encoding over the most efficient one.
@@ -505,9 +562,8 @@
                 callargs = [r.r0, r.r1, r.r2]
             remap_frame_layout(self, arglocs, callargs, r.ip)
             func = rffi.cast(lltype.Signed, addr)
-            #
-            # misaligned stack in the call, but it's ok because the write barrier
-            # is not going to call anything more.  
+            # misaligned stack in the call, but it's ok because the write
+            # barrier is not going to call anything more.
             self.mc.BL(func)
 
         # patch the JZ above
@@ -518,6 +574,7 @@
 
     emit_op_cond_call_gc_wb_array = emit_op_cond_call_gc_wb
 
+
 class FieldOpAssembler(object):
 
     _mixin_ = True
@@ -600,7 +657,8 @@
     emit_op_getfield_gc_pure = emit_op_getfield_gc
 
     def emit_op_getinteriorfield_gc(self, op, arglocs, regalloc, fcond):
-        base_loc, index_loc, res_loc, ofs_loc, ofs, itemsize, fieldsize = arglocs
+        (base_loc, index_loc, res_loc,
+            ofs_loc, ofs, itemsize, fieldsize) = arglocs
         self.mc.gen_load_int(r.ip.value, itemsize.value)
         self.mc.MUL(r.ip.value, index_loc.value, r.ip.value)
         if ofs.value > 0:
@@ -632,7 +690,8 @@
         return fcond
 
     def emit_op_setinteriorfield_gc(self, op, arglocs, regalloc, fcond):
-        base_loc, index_loc, value_loc, ofs_loc, ofs, itemsize, fieldsize = arglocs
+        (base_loc, index_loc, value_loc,
+            ofs_loc, ofs, itemsize, fieldsize) = arglocs
         self.mc.gen_load_int(r.ip.value, itemsize.value)
         self.mc.MUL(r.ip.value, index_loc.value, r.ip.value)
         if ofs.value > 0:
@@ -658,8 +717,6 @@
         return fcond
 
 
-
-
 class ArrayOpAssember(object):
 
     _mixin_ = True
@@ -678,7 +735,7 @@
         else:
             scale_loc = ofs_loc
 
-        # add the base offset  
+        # add the base offset
         if ofs.value > 0:
             self.mc.ADD_ri(r.ip.value, scale_loc.value, imm=ofs.value)
             scale_loc = r.ip
@@ -689,11 +746,14 @@
             self.mc.ADD_rr(r.ip.value, base_loc.value, scale_loc.value)
             self.mc.VSTR(value_loc.value, r.ip.value, cond=fcond)
         elif scale.value == 2:
-            self.mc.STR_rr(value_loc.value, base_loc.value, scale_loc.value, cond=fcond)
+            self.mc.STR_rr(value_loc.value, base_loc.value, scale_loc.value,
+                                                                    cond=fcond)
         elif scale.value == 1:
-            self.mc.STRH_rr(value_loc.value, base_loc.value, scale_loc.value, cond=fcond)
+            self.mc.STRH_rr(value_loc.value, base_loc.value, scale_loc.value,
+                                                                    cond=fcond)
         elif scale.value == 0:
-            self.mc.STRB_rr(value_loc.value, base_loc.value, scale_loc.value, cond=fcond)
+            self.mc.STRB_rr(value_loc.value, base_loc.value, scale_loc.value,
+                                                                    cond=fcond)
         else:
             assert 0
         return fcond
@@ -709,7 +769,7 @@
         else:
             scale_loc = ofs_loc
 
-        # add the base offset  
+        # add the base offset
         if ofs.value > 0:
             self.mc.ADD_ri(r.ip.value, scale_loc.value, imm=ofs.value)
             scale_loc = r.ip
@@ -720,18 +780,21 @@
             self.mc.ADD_rr(r.ip.value, base_loc.value, scale_loc.value)
             self.mc.VLDR(res.value, r.ip.value, cond=fcond)
         elif scale.value == 2:
-            self.mc.LDR_rr(res.value, base_loc.value, scale_loc.value, cond=fcond)
+            self.mc.LDR_rr(res.value, base_loc.value, scale_loc.value,
+                                                                cond=fcond)
         elif scale.value == 1:
-            self.mc.LDRH_rr(res.value, base_loc.value, scale_loc.value, cond=fcond)
+            self.mc.LDRH_rr(res.value, base_loc.value, scale_loc.value,
+                                                                cond=fcond)
         elif scale.value == 0:
-            self.mc.LDRB_rr(res.value, base_loc.value, scale_loc.value, cond=fcond)
+            self.mc.LDRB_rr(res.value, base_loc.value, scale_loc.value,
+                                                                cond=fcond)
         else:
             assert 0
 
         #XXX Hack, Hack, Hack
         if not we_are_translated():
             descr = op.getdescr()
-            size =  descr.get_item_size(False)
+            size = descr.itemsize
             signed = descr.is_item_signed()
             self._ensure_result_bit_extension(res, size, signed)
         return fcond
@@ -755,9 +818,11 @@
     def emit_op_strgetitem(self, op, arglocs, regalloc, fcond):
         res, base_loc, ofs_loc, basesize = arglocs
         if ofs_loc.is_imm():
-            self.mc.ADD_ri(r.ip.value, base_loc.value, ofs_loc.getint(), cond=fcond)
+            self.mc.ADD_ri(r.ip.value, base_loc.value, ofs_loc.getint(),
+                                                                    cond=fcond)
         else:
-            self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value, cond=fcond)
+            self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value,
+                                                                    cond=fcond)
 
         self.mc.LDRB_ri(res.value, r.ip.value, basesize.value, cond=fcond)
         return fcond
@@ -765,11 +830,14 @@
     def emit_op_strsetitem(self, op, arglocs, regalloc, fcond):
         value_loc, base_loc, ofs_loc, basesize = arglocs
         if ofs_loc.is_imm():
-            self.mc.ADD_ri(r.ip.value, base_loc.value, ofs_loc.getint(), cond=fcond)
+            self.mc.ADD_ri(r.ip.value, base_loc.value, ofs_loc.getint(),
+                                                            cond=fcond)
         else:
-            self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value, cond=fcond)
+            self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value,
+                                                            cond=fcond)
 
-        self.mc.STRB_ri(value_loc.value, r.ip.value, basesize.value, cond=fcond)
+        self.mc.STRB_ri(value_loc.value, r.ip.value, basesize.value,
+                                                            cond=fcond)
         return fcond
 
     #from ../x86/regalloc.py:928 ff.
@@ -785,71 +853,78 @@
 
     def _emit_copystrcontent(self, op, regalloc, fcond, is_unicode):
         # compute the source address
-        args = list(op.getarglist())
-        base_loc, box = regalloc._ensure_value_is_boxed(args[0], args)
-        args.append(box)
-        ofs_loc, box = regalloc._ensure_value_is_boxed(args[2], args)
-        args.append(box)
+        args = op.getarglist()
+        base_loc = regalloc._ensure_value_is_boxed(args[0], args)
+        ofs_loc = regalloc._ensure_value_is_boxed(args[2], args)
         assert args[0] is not args[1]    # forbidden case of aliasing
         regalloc.possibly_free_var(args[0])
+        regalloc.free_temp_vars()
         if args[3] is not args[2] is not args[4]:  # MESS MESS MESS: don't free
-            regalloc.possibly_free_var(args[2])     # it if ==args[3] or args[4]
+            regalloc.possibly_free_var(args[2])  # it if ==args[3] or args[4]
+            regalloc.free_temp_vars()
         srcaddr_box = TempPtr()
         forbidden_vars = [args[1], args[3], args[4], srcaddr_box]
-        srcaddr_loc = regalloc.force_allocate_reg(srcaddr_box, selected_reg=r.r1)
+        srcaddr_loc = regalloc.force_allocate_reg(srcaddr_box,
+                                                        selected_reg=r.r1)
         self._gen_address_inside_string(base_loc, ofs_loc, srcaddr_loc,
                                         is_unicode=is_unicode)
 
         # compute the destination address
         forbidden_vars = [args[4], args[3], srcaddr_box]
         dstaddr_box = TempPtr()
-        dstaddr_loc = regalloc.force_allocate_reg(dstaddr_box, selected_reg=r.r0)
+        dstaddr_loc = regalloc.force_allocate_reg(dstaddr_box,
+                                                        selected_reg=r.r0)
         forbidden_vars.append(dstaddr_box)
-        base_loc, box = regalloc._ensure_value_is_boxed(args[1], forbidden_vars)
-        args.append(box)
-        forbidden_vars.append(box)
-        ofs_loc, box = regalloc._ensure_value_is_boxed(args[3], forbidden_vars)
-        args.append(box)
+        base_loc = regalloc._ensure_value_is_boxed(args[1], forbidden_vars)
+        ofs_loc = regalloc._ensure_value_is_boxed(args[3], forbidden_vars)
         assert base_loc.is_reg()
         assert ofs_loc.is_reg()
         regalloc.possibly_free_var(args[1])
         if args[3] is not args[4]:     # more of the MESS described above
             regalloc.possibly_free_var(args[3])
+        regalloc.free_temp_vars()
         self._gen_address_inside_string(base_loc, ofs_loc, dstaddr_loc,
                                         is_unicode=is_unicode)
 
         # compute the length in bytes
         forbidden_vars = [srcaddr_box, dstaddr_box]
-        length_loc, length_box = regalloc._ensure_value_is_boxed(args[4], forbidden_vars)
-        args.append(length_box)
+        # XXX basically duplicates regalloc.ensure_value_is_boxed, but we
+        # need the box here
+        if isinstance(args[4], Box):
+            length_box = args[4]
+            length_loc = regalloc.make_sure_var_in_reg(args[4], forbidden_vars)
+        else:
+            length_box = TempInt()
+            length_loc = regalloc.force_allocate_reg(length_box,
+                                        forbidden_vars, selected_reg=r.r2)
+            imm = regalloc.convert_to_imm(args[4])
+            self.load(length_loc, imm)
         if is_unicode:
-            forbidden_vars = [srcaddr_box, dstaddr_box]
             bytes_box = TempPtr()
-            bytes_loc = regalloc.force_allocate_reg(bytes_box, forbidden_vars)
+            bytes_loc = regalloc.force_allocate_reg(bytes_box,
+                                        forbidden_vars, selected_reg=r.r2)
             scale = self._get_unicode_item_scale()
             assert length_loc.is_reg()
-            self.mc.MOV_ri(r.ip.value, 1<<scale)
+            self.mc.MOV_ri(r.ip.value, 1 << scale)
             self.mc.MUL(bytes_loc.value, r.ip.value, length_loc.value)
             length_box = bytes_box
             length_loc = bytes_loc
         # call memcpy()
-        self._emit_call(NO_FORCE_INDEX, self.memcpy_addr, [dstaddr_box, srcaddr_box, length_box], regalloc)
+        self._emit_call(NO_FORCE_INDEX, self.memcpy_addr,
+                            [dstaddr_box, srcaddr_box, length_box], regalloc)
 
-        regalloc.possibly_free_vars(args)
         regalloc.possibly_free_var(length_box)
         regalloc.possibly_free_var(dstaddr_box)
         regalloc.possibly_free_var(srcaddr_box)
 
-
     def _gen_address_inside_string(self, baseloc, ofsloc, resloc, is_unicode):
-        cpu = self.cpu
         if is_unicode:
             ofs_items, _, _ = symbolic.get_array_token(rstr.UNICODE,
-                                                  self.cpu.translate_support_code)
+                                              self.cpu.translate_support_code)
             scale = self._get_unicode_item_scale()
         else:
             ofs_items, itemsize, _ = symbolic.get_array_token(rstr.STR,
-                                                  self.cpu.translate_support_code)
+                                              self.cpu.translate_support_code)
             assert itemsize == 1
             scale = 0
         self._gen_address(ofsloc, ofs_items, scale, resloc, baseloc)
@@ -870,7 +945,7 @@
 
     def _get_unicode_item_scale(self):
         _, itemsize, _ = symbolic.get_array_token(rstr.UNICODE,
-                                                  self.cpu.translate_support_code)
+                                              self.cpu.translate_support_code)
         if itemsize == 4:
             return 2
         elif itemsize == 2:
@@ -878,6 +953,7 @@
         else:
             raise AssertionError("bad unicode item size")
 
+
 class UnicodeOpAssembler(object):
 
     _mixin_ = True
@@ -887,7 +963,7 @@
     def emit_op_unicodegetitem(self, op, arglocs, regalloc, fcond):
         res, base_loc, ofs_loc, scale, basesize, itemsize = arglocs
         self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value, cond=fcond,
-                                            imm=scale.value, shifttype=shift.LSL)
+                                        imm=scale.value, shifttype=shift.LSL)
         if scale.value == 2:
             self.mc.LDR_ri(res.value, r.ip.value, basesize.value, cond=fcond)
         elif scale.value == 1:
@@ -901,14 +977,17 @@
         self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value, cond=fcond,
                                         imm=scale.value, shifttype=shift.LSL)
         if scale.value == 2:
-            self.mc.STR_ri(value_loc.value, r.ip.value, basesize.value, cond=fcond)
+            self.mc.STR_ri(value_loc.value, r.ip.value, basesize.value,
+                                                                    cond=fcond)
         elif scale.value == 1:
-            self.mc.STRH_ri(value_loc.value, r.ip.value, basesize.value, cond=fcond)
+            self.mc.STRH_ri(value_loc.value, r.ip.value, basesize.value,
+                                                                    cond=fcond)
         else:
             assert 0, itemsize.value
 
         return fcond
 
+
 class ForceOpAssembler(object):
 
     _mixin_ = True
@@ -920,18 +999,19 @@
 
     # from: ../x86/assembler.py:1668
     # XXX Split into some helper methods
-    def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc, fcond):
+    def emit_guard_call_assembler(self, op, guard_op, arglocs, regalloc,
+                                                                    fcond):
         faildescr = guard_op.getdescr()
         fail_index = self.cpu.get_fail_descr_number(faildescr)
         self._write_fail_index(fail_index)
 
         descr = op.getdescr()
-        assert isinstance(descr, LoopToken)
+        assert isinstance(descr, JitCellToken)
         # XXX check this
-        assert op.numargs() == len(descr._arm_arglocs[0])
+        # assert len(arglocs) - 2 == descr.compiled_loop_token._debug_nbargs
         resbox = TempInt()
-        self._emit_call(fail_index, descr._arm_direct_bootstrap_code, op.getarglist(),
-                                regalloc, fcond, result=resbox)
+        self._emit_call(fail_index, descr._arm_func_addr,
+                        op.getarglist(), regalloc, fcond, result=resbox)
         if op.result is None:
             value = self.cpu.done_with_this_frame_void_v
         else:
@@ -952,7 +1032,7 @@
         regalloc.possibly_free_var(resbox)
 
         fast_jmp_pos = self.mc.currpos()
-        self.mc.NOP()
+        self.mc.BKPT()
 
         # Path A: use assembler helper
         #if values are equal we take the fast path
@@ -961,7 +1041,7 @@
         jd = descr.outermost_jitdriver_sd
         assert jd is not None
         asm_helper_adr = self.cpu.cast_adr_to_int(jd.assembler_helper_adr)
-        with saved_registers(self.mc, r.caller_resp[1:]+[r.ip], 
+        with saved_registers(self.mc, r.caller_resp[1:] + [r.ip],
                                     r.caller_vfp_resp):
             # resbox is allready in r0
             self.mov_loc_loc(arglocs[1], r.r1)
@@ -974,7 +1054,8 @@
 
         # jump to merge point
         jmp_pos = self.mc.currpos()
-        #jmp_location = self.mc.curraddr()
+        # This location is not necessarily patched later, depending on how many
+        # instructions we emit from here to the merge point below.
         self.mc.NOP()
 
         # Path B: load return value and reset token
@@ -986,9 +1067,9 @@
 
         # Reset the vable token --- XXX really too much special logic here:-(
         if jd.index_of_virtualizable >= 0:
-            from pypy.jit.backend.llsupport.descr import BaseFieldDescr
+            from pypy.jit.backend.llsupport.descr import FieldDescr
             fielddescr = jd.vable_token_descr
-            assert isinstance(fielddescr, BaseFieldDescr)
+            assert isinstance(fielddescr, FieldDescr)
             ofs = fielddescr.offset
             resloc = regalloc.force_allocate_reg(resbox)
             self.mov_loc_loc(arglocs[1], r.ip)
@@ -1024,26 +1105,31 @@
         self.mc.LDR_ri(r.ip.value, r.fp.value)
         self.mc.CMP_ri(r.ip.value, 0)
 
-        self._emit_guard(guard_op, regalloc._prepare_guard(guard_op), c.GE)
+        self._emit_guard(guard_op, regalloc._prepare_guard(guard_op),
+                                                    c.GE, save_exc=True)
         return fcond
 
-
     # ../x86/assembler.py:668
     def redirect_call_assembler(self, oldlooptoken, newlooptoken):
-        # we overwrite the instructions at the old _x86_direct_bootstrap_code
-        # to start with a JMP to the new _arm_direct_bootstrap_code.
+        # some minimal sanity checking
+        old_nbargs = oldlooptoken.compiled_loop_token._debug_nbargs
+        new_nbargs = newlooptoken.compiled_loop_token._debug_nbargs
+        assert old_nbargs == new_nbargs
+        # we overwrite the instructions at the old _arm_func_adddr
+        # to start with a JMP to the new _arm_func_addr.
         # Ideally we should rather patch all existing CALLs, but well.
-        oldadr = oldlooptoken._arm_direct_bootstrap_code
-        target = newlooptoken._arm_direct_bootstrap_code
+        oldadr = oldlooptoken._arm_func_addr
+        target = newlooptoken._arm_func_addr
         mc = ARMv7Builder()
         mc.B(target)
         mc.copy_to_raw_memory(oldadr)
 
-    def emit_guard_call_may_force(self, op, guard_op, arglocs, regalloc, fcond):
+    def emit_guard_call_may_force(self, op, guard_op, arglocs, regalloc,
+                                                                    fcond):
         self.mc.LDR_ri(r.ip.value, r.fp.value)
         self.mc.CMP_ri(r.ip.value, 0)
 
-        self._emit_guard(guard_op, arglocs, c.GE)
+        self._emit_guard(guard_op, arglocs, c.GE, save_exc=True)
         return fcond
 
     emit_guard_call_release_gil = emit_guard_call_may_force
@@ -1058,21 +1144,26 @@
                 regs_to_save.append(reg)
         assert gcrootmap.is_shadow_stack
         with saved_registers(self.mc, regs_to_save):
-            self._emit_call(-1, self.releasegil_addr, [], self._regalloc, fcond)
+            self._emit_call(NO_FORCE_INDEX, self.releasegil_addr, [],
+                                                    self._regalloc, fcond)
 
     def call_reacquire_gil(self, gcrootmap, save_loc, fcond):
         # save the previous result into the stack temporarily.
         # XXX like with call_release_gil(), we assume that we don't need
-        # to save vfp regs in this case.
+        # to save vfp regs in this case. Besides the result location
         regs_to_save = []
+        vfp_regs_to_save = []
         if save_loc.is_reg():
             regs_to_save.append(save_loc)
+        if save_loc.is_vfp_reg():
+            vfp_regs_to_save.append(save_loc)
         # call the reopenstack() function (also reacquiring the GIL)
-        if len(regs_to_save) == 1:
-            regs_to_save.append(r.ip) # for alingment
+        if len(regs_to_save) % 2 != 1:
+            regs_to_save.append(r.ip)  # for alingment
         assert gcrootmap.is_shadow_stack
-        with saved_registers(self.mc, regs_to_save):
-            self._emit_call(-1, self.reacqgil_addr, [], self._regalloc, fcond)
+        with saved_registers(self.mc, regs_to_save, vfp_regs_to_save):
+            self._emit_call(NO_FORCE_INDEX, self.reacqgil_addr, [],
+                                                    self._regalloc, fcond)
 
     def write_new_force_index(self):
         # for shadowstack only: get a new, unused force_index number and
@@ -1092,54 +1183,16 @@
         self.mc.gen_load_int(r.ip.value, fail_index)
         self.mc.STR_ri(r.ip.value, r.fp.value)
 
+
 class AllocOpAssembler(object):
 
     _mixin_ = True
 
-
-    # from: ../x86/regalloc.py:750
-    # called from regalloc
-    # XXX kill this function at some point
-    def _regalloc_malloc_varsize(self, size, size_box, vloc, vbox, ofs_items_loc, regalloc, result):
-        self.mc.MUL(size.value, size.value, vloc.value)
-        if ofs_items_loc.is_imm():
-            self.mc.ADD_ri(size.value, size.value, ofs_items_loc.value)
-        else:
-            self.mc.ADD_rr(size.value, size.value, ofs_items_loc.value)
-        force_index = self.write_new_force_index()
-        regalloc.force_spill_var(vbox)
-        self._emit_call(force_index, self.malloc_func_addr, [size_box], regalloc,
-                                    result=result)
-
-    def emit_op_new(self, op, arglocs, regalloc, fcond):
+    def emit_op_call_malloc_gc(self, op, arglocs, regalloc, fcond):
+        self.emit_op_call(op, arglocs, regalloc, fcond)
         self.propagate_memoryerror_if_r0_is_null()
         return fcond
 
-    def emit_op_new_with_vtable(self, op, arglocs, regalloc, fcond):
-        classint = arglocs[0].value
-        self.set_vtable(op.result, classint)
-        return fcond
-
-    def set_vtable(self, box, vtable):
-        if self.cpu.vtable_offset is not None:
-            adr = rffi.cast(lltype.Signed, vtable)
-            self.mc.gen_load_int(r.ip.value, adr)
-            self.mc.STR_ri(r.ip.value, r.r0.value, self.cpu.vtable_offset)
-
-    def set_new_array_length(self, loc, ofs_length, loc_num_elem):
-        assert loc.is_reg()
-        self.mc.gen_load_int(r.ip.value, loc_num_elem)
-        self.mc.STR_ri(r.ip.value, loc.value, imm=ofs_length)
-
-    def emit_op_new_array(self, op, arglocs, regalloc, fcond):
-        self.propagate_memoryerror_if_r0_is_null()
-        if len(arglocs) > 0:
-            value_loc, base_loc, ofs_length = arglocs
-            self.mc.STR_ri(value_loc.value, base_loc.value, ofs_length.value)
-        return fcond
-
-    emit_op_newstr = emit_op_new_array
-    emit_op_newunicode = emit_op_new_array
 
 class FloatOpAssemlber(object):
     _mixin_ = True
@@ -1182,6 +1235,7 @@
         self.mc.VCVT_int_to_float(res.value, temp.value)
         return fcond
 
+
 class ResOpAssembler(GuardOpAssembler, IntOpAsslember,
                     OpAssembler, UnaryIntOpAssembler,
                     FieldOpAssembler, ArrayOpAssember,
@@ -1189,4 +1243,3 @@
                     ForceOpAssembler, AllocOpAssembler,
                     FloatOpAssemlber):
     pass
-
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -1,5 +1,5 @@
 from pypy.jit.backend.llsupport.regalloc import FrameManager, \
-        RegisterManager, compute_vars_longevity, TempBox, compute_loop_consts
+        RegisterManager, TempBox, compute_vars_longevity
 from pypy.jit.backend.arm import registers as r
 from pypy.jit.backend.arm import locations
 from pypy.jit.backend.arm.locations import imm
@@ -8,22 +8,30 @@
                                                     prepare_op_ri,
                                                     prepare_cmp_op,
                                                     prepare_float_op,
-                                                    _check_imm_arg)
+                                                    check_imm_arg,
+                                                    check_imm_box
+                                                    )
 from pypy.jit.backend.arm.jump import remap_frame_layout_mixed
-from pypy.jit.backend.arm.arch import MY_COPY_OF_REGS, WORD
+from pypy.jit.backend.arm.arch import MY_COPY_OF_REGS
+from pypy.jit.backend.arm.arch import WORD, N_REGISTERS_SAVED_BY_MALLOC
 from pypy.jit.codewriter import longlong
 from pypy.jit.metainterp.history import (Const, ConstInt, ConstFloat, ConstPtr,
-                                        Box, BoxInt, BoxPtr, AbstractFailDescr,
-                                        INT, REF, FLOAT, LoopToken)
+                                        Box, BoxPtr,
+                                        INT, REF, FLOAT)
+from pypy.jit.metainterp.history import JitCellToken, TargetToken
 from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.backend.llsupport.descr import BaseFieldDescr, BaseArrayDescr, \
-                                             BaseCallDescr, BaseSizeDescr, \
-                                             InteriorFieldDescr
+from pypy.jit.backend.llsupport.descr import ArrayDescr
 from pypy.jit.backend.llsupport import symbolic
-from pypy.rpython.lltypesystem import lltype, rffi, rstr, llmemory
-from pypy.jit.codewriter import heaptracker
+from pypy.rpython.lltypesystem import lltype, rffi, rstr
 from pypy.jit.codewriter.effectinfo import EffectInfo
-from pypy.rlib.objectmodel import we_are_translated
+from pypy.jit.backend.llsupport.descr import unpack_arraydescr
+from pypy.jit.backend.llsupport.descr import unpack_fielddescr
+from pypy.jit.backend.llsupport.descr import unpack_interiorfielddescr
+
+
+# xxx hack: set a default value for TargetToken._arm_loop_code.  If 0, we know
+# that it is a LABEL that was not compiled yet.
+TargetToken._arm_loop_code = 0
 
 class TempInt(TempBox):
     type = INT
@@ -31,27 +39,40 @@
     def __repr__(self):
         return "<TempInt at %s>" % (id(self),)
 
+
 class TempPtr(TempBox):
     type = REF
 
     def __repr__(self):
         return "<TempPtr at %s>" % (id(self),)
 
+
 class TempFloat(TempBox):
     type = FLOAT
 
     def __repr__(self):
         return "<TempFloat at %s>" % (id(self),)
 
+
 class ARMFrameManager(FrameManager):
+
     def __init__(self):
         FrameManager.__init__(self)
-        self.frame_depth = 1
+        self.used = [True]  # keep first slot free
+        # XXX refactor frame to avoid this issue of keeping the first slot
+        # reserved
+
     @staticmethod
     def frame_pos(loc, type):
         num_words = ARMFrameManager.frame_size(type)
         if type == FLOAT:
-            return locations.StackLocation(loc+1, num_words=num_words, type=type)
+            if loc > 0:
+                # Make sure that loc is an even value
+                # the frame layout requires loc to be even if it is a spilled
+                # value!!
+                assert (loc & 1) == 0
+            return locations.StackLocation(loc + 1,
+                            num_words=num_words, type=type)
         return locations.StackLocation(loc, num_words=num_words, type=type)
 
     @staticmethod
@@ -60,9 +81,19 @@
             return  2
         return 1
 
+    @staticmethod
+    def get_loc_index(loc):
+        assert loc.is_stack()
+        if loc.type == FLOAT:
+            return loc.position - 1
+        else:
+            return loc.position
+
+
 def void(self, op, fcond):
     return []
 
+
 class VFPRegisterManager(RegisterManager):
     all_regs = r.all_vfp_regs
     box_types = [FLOAT]
@@ -84,10 +115,33 @@
         self._check_type(v)
         r = self.force_allocate_reg(v)
         return r
-class ARMv7RegisterMananger(RegisterManager):
-    all_regs              = r.all_regs
-    box_types             = None       # or a list of acceptable types
-    no_lower_byte_regs    = all_regs
+
+    def ensure_value_is_boxed(self, thing, forbidden_vars=[]):
+        loc = None
+        if isinstance(thing, Const):
+            assert isinstance(thing, ConstFloat)
+            loc = self.get_scratch_reg(FLOAT, self.temp_boxes + forbidden_vars)
+            immvalue = self.convert_to_imm(thing)
+            self.assembler.load(loc, immvalue)
+        else:
+            loc = self.make_sure_var_in_reg(thing,
+                            forbidden_vars=self.temp_boxes + forbidden_vars)
+        return loc
+
+    def get_scratch_reg(self, type=FLOAT, forbidden_vars=[],
+                                                        selected_reg=None):
+        assert type == FLOAT  # for now
+        box = TempFloat()
+        self.temp_boxes.append(box)
+        reg = self.force_allocate_reg(box, forbidden_vars=forbidden_vars,
+                                                    selected_reg=selected_reg)
+        return reg
+
+
+class ARMv7RegisterManager(RegisterManager):
+    all_regs = r.all_regs
+    box_types = None       # or a list of acceptable types
+    no_lower_byte_regs = all_regs
     save_around_call_regs = r.caller_resp
 
     REGLOC_TO_COPY_AREA_OFS = {
@@ -110,27 +164,53 @@
 
     def convert_to_imm(self, c):
         if isinstance(c, ConstInt):
-            return locations.ImmLocation(c.value)
+            val = rffi.cast(rffi.INT, c.value)
+            return locations.ImmLocation(val)
         else:
             assert isinstance(c, ConstPtr)
             return locations.ImmLocation(rffi.cast(lltype.Signed, c.value))
-    
+        assert 0
+
+    def ensure_value_is_boxed(self, thing, forbidden_vars=None):
+        loc = None
+        if isinstance(thing, Const):
+            if isinstance(thing, ConstPtr):
+                tp = REF
+            else:
+                tp = INT
+            loc = self.get_scratch_reg(tp, forbidden_vars=self.temp_boxes
+                                                            + forbidden_vars)
+            immvalue = self.convert_to_imm(thing)
+            self.assembler.load(loc, immvalue)
+        else:
+            loc = self.make_sure_var_in_reg(thing,
+                            forbidden_vars=forbidden_vars)
+        return loc
+
+    def get_scratch_reg(self, type=INT, forbidden_vars=[], selected_reg=None):
+        assert type == INT or type == REF
+        box = TempBox()
+        self.temp_boxes.append(box)
+        reg = self.force_allocate_reg(box, forbidden_vars=forbidden_vars,
+                                                    selected_reg=selected_reg)
+        return reg
+
+
 class Regalloc(object):
 
-    def __init__(self, longevity, frame_manager=None, assembler=None):
+    def __init__(self, frame_manager=None, assembler=None):
         self.cpu = assembler.cpu
-        self.longevity = longevity
+        self.assembler = assembler
         self.frame_manager = frame_manager
-        self.assembler = assembler
-        self.vfprm = VFPRegisterManager(longevity, frame_manager, assembler)
-        self.rm = ARMv7RegisterMananger(longevity, frame_manager, assembler)
+        self.jump_target_descr = None
+        self.final_jump_op = None
 
     def loc(self, var):
         if var.type == FLOAT:
             return self.vfprm.loc(var)
         else:
             return self.rm.loc(var)
-    
+
     def position(self):
         return self.rm.position
 
@@ -168,9 +248,11 @@
         else:
             return self.rm.force_allocate_reg(var, forbidden_vars,
                                               selected_reg, need_lower_byte)
+
     def try_allocate_reg(self, v, selected_reg=None, need_lower_byte=False):
         if v.type == FLOAT:
-            return self.vfprm.try_allocate_reg(v, selected_reg, need_lower_byte)
+            return self.vfprm.try_allocate_reg(v, selected_reg,
+                                                            need_lower_byte)
         else:
             return self.rm.try_allocate_reg(v, selected_reg, need_lower_byte)
 
@@ -183,14 +265,25 @@
     def possibly_free_vars_for_op(self, op):
         for i in range(op.numargs()):
             var = op.getarg(i)
-            if var is not None: # xxx kludgy
+            if var is not None:  # xxx kludgy
                 self.possibly_free_var(var)
 
     def possibly_free_vars(self, vars):
         for var in vars:
-            if var is not None: # xxx kludgy
+            if var is not None:  # xxx kludgy
                 self.possibly_free_var(var)
 
+    def get_scratch_reg(self, type, forbidden_vars=[], selected_reg=None):
+        if type == FLOAT:
+            return self.vfprm.get_scratch_reg(type, forbidden_vars,
+                                                                selected_reg)
+        else:
+            return self.rm.get_scratch_reg(type, forbidden_vars, selected_reg)
+
+    def free_temp_vars(self):
+        self.rm.free_temp_vars()
+        self.vfprm.free_temp_vars()
+
     def make_sure_var_in_reg(self, var, forbidden_vars=[],
                          selected_reg=None, need_lower_byte=False):
         if var.type == FLOAT:
@@ -207,31 +300,68 @@
             assert isinstance(value, ConstFloat)
             return self.vfprm.convert_to_imm(value)
 
-    def prepare_loop(self, inputargs, operations, looptoken):
-        loop_consts = compute_loop_consts(inputargs, operations[-1], looptoken)
-        floatlocs = [None] * len(inputargs)
-        nonfloatlocs = [None] * len(inputargs)
-        for i in range(len(inputargs)):
-            arg = inputargs[i]
-            assert not isinstance(arg, Const)
-            reg = None
-            loc = inputargs[i]
-            if arg not in loop_consts and self.longevity[arg][1] > -1:
-                reg = self.try_allocate_reg(loc)
+    def _prepare(self,  inputargs, operations):
+        longevity, last_real_usage = compute_vars_longevity(
+                                                    inputargs, operations)
+        self.longevity = longevity
+        self.last_real_usage = last_real_usage
+        fm = self.frame_manager
+        asm = self.assembler
+        self.vfprm = VFPRegisterManager(longevity, fm, asm)
+        self.rm = ARMv7RegisterManager(longevity, fm, asm)
 
-            loc = self.loc(arg)
-            if arg.type == FLOAT:
-                floatlocs[i] = loc
+    def prepare_loop(self, inputargs, operations):
+        self._prepare(inputargs, operations)
+        self._set_initial_bindings(inputargs)
+        self.possibly_free_vars(list(inputargs))
+
+    def prepare_bridge(self, inputargs, arglocs, ops):
+        self._prepare(inputargs, ops)
+        self._update_bindings(arglocs, inputargs)
+
+    def _set_initial_bindings(self, inputargs):
+        # The first inputargs are passed in registers r0-r3
+        # we relly on the soft-float calling convention so we need to move
+        # float params to the coprocessor.
+
+        arg_index = 0
+        count = 0
+        n_register_args = len(r.argument_regs)
+        cur_frame_pos = - (self.assembler.STACK_FIXED_AREA / WORD) + 1
+        for box in inputargs:
+            assert isinstance(box, Box)
+            # handle inputargs in argument registers
+            if box.type == FLOAT and arg_index % 2 != 0:
+                arg_index += 1  # align argument index for float passed
+                                # in register
+            if arg_index < n_register_args:
+                if box.type == FLOAT:
+                    loc = r.argument_regs[arg_index]
+                    loc2 = r.argument_regs[arg_index + 1]
+                    vfpreg = self.try_allocate_reg(box)
+                    # move soft-float argument to vfp
+                    self.assembler.mov_to_vfp_loc(loc, loc2, vfpreg)
+                    arg_index += 2  # this argument used to argument registers
+                else:
+                    loc = r.argument_regs[arg_index]
+                    self.try_allocate_reg(box, selected_reg=loc)
+                    arg_index += 1
             else:
-                nonfloatlocs[i] = loc
-        self.possibly_free_vars(list(inputargs))
-        
-        return nonfloatlocs, floatlocs
+                # treat stack args as stack locations with a negative offset
+                if box.type == FLOAT:
+                    cur_frame_pos -= 2
+                    if count % 2 != 0: # Stack argument alignment
+                        cur_frame_pos -= 1
+                        count = 0
+                else:
+                    cur_frame_pos -= 1
+                    count += 1
+                loc = self.frame_manager.frame_pos(cur_frame_pos, box.type)
+                self.frame_manager.set_binding(box, loc)
 
-    def update_bindings(self, locs, frame_depth, inputargs):
+    def _update_bindings(self, locs, inputargs):
         used = {}
         i = 0
-        self.frame_manager.frame_depth = frame_depth
         for loc in locs:
             arg = inputargs[i]
             i += 1
@@ -241,7 +371,7 @@
                 self.vfprm.reg_bindings[arg] = loc
             else:
                 assert loc.is_stack()
-                self.frame_manager.frame_bindings[arg] = loc
+                self.frame_manager.set_binding(arg, loc)
             used[loc] = None
 
         # XXX combine with x86 code and move to llsupport
@@ -257,7 +387,6 @@
         # is also used on op args, which is a non-resizable list
         self.possibly_free_vars(list(inputargs))
 
-
     def force_spill_var(self, var):
         if var.type == FLOAT:
             self.vfprm.force_spill_var(var)
@@ -267,28 +396,12 @@
     def before_call(self, force_store=[], save_all_regs=False):
         self.rm.before_call(force_store, save_all_regs)
         self.vfprm.before_call(force_store, save_all_regs)
+
     def _ensure_value_is_boxed(self, thing, forbidden_vars=[]):
-        box = None
-        loc = None
-        if isinstance(thing, Const):
-            if isinstance(thing, ConstPtr):
-                box = TempPtr()
-            elif isinstance(thing, ConstFloat):
-                box = TempFloat()
-            else:
-                box = TempInt()
-            loc = self.force_allocate_reg(box,
-                            forbidden_vars=forbidden_vars)
-            if isinstance(thing, ConstFloat):
-               imm = self.vfprm.convert_to_imm(thing) 
-            else:
-                imm = self.rm.convert_to_imm(thing)
-            self.assembler.load(loc, imm)
+        if thing.type == FLOAT:
+            return self.vfprm.ensure_value_is_boxed(thing, forbidden_vars)
         else:
-            loc = self.make_sure_var_in_reg(thing,
-                            forbidden_vars=forbidden_vars)
-            box = thing
-        return loc, box
+            return self.rm.ensure_value_is_boxed(thing, forbidden_vars)
 
     def _sync_var(self, v):
         if v.type == FLOAT:
@@ -299,52 +412,45 @@
     def _prepare_op_int_add(self, op, fcond):
         boxes = list(op.getarglist())
         a0, a1 = boxes
-        imm_a0 = _check_imm_arg(a0)
-        imm_a1 = _check_imm_arg(a1)
+        imm_a0 = check_imm_box(a0)
+        imm_a1 = check_imm_box(a1)
         if not imm_a0 and imm_a1:
-            l0, box = self._ensure_value_is_boxed(a0)
-            l1 = self.make_sure_var_in_reg(a1, [a0])
-            boxes.append(box)
+            l0 = self._ensure_value_is_boxed(a0)
+            l1 = self.make_sure_var_in_reg(a1, boxes)
         elif imm_a0 and not imm_a1:
             l0 = self.make_sure_var_in_reg(a0)
-            l1, box = self._ensure_value_is_boxed(a1, [a0])
-            boxes.append(box)
+            l1 = self._ensure_value_is_boxed(a1, boxes)
         else:
-            l0, box = self._ensure_value_is_boxed(a0)
-            boxes.append(box)
-            l1, box = self._ensure_value_is_boxed(a1, [box])
-            boxes.append(box)
-        return [l0, l1], boxes
+            l0 = self._ensure_value_is_boxed(a0)
+            l1 = self._ensure_value_is_boxed(a1, boxes)
+        return [l0, l1]
 
     def prepare_op_int_add(self, op, fcond):
-        locs, boxes = self._prepare_op_int_add(op, fcond)
-        self.possibly_free_vars(boxes)
+        locs = self._prepare_op_int_add(op, fcond)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
         return locs + [res]
 
     def _prepare_op_int_sub(self, op, fcond):
-        boxes = list(op.getarglist())
-        a0, a1 = boxes
-        imm_a0 = _check_imm_arg(a0)
-        imm_a1 = _check_imm_arg(a1)
+        a0, a1 = boxes = op.getarglist()
+        imm_a0 = check_imm_box(a0)
+        imm_a1 = check_imm_box(a1)
         if not imm_a0 and imm_a1:
-            l0, box = self._ensure_value_is_boxed(a0, boxes)
-            l1 = self.make_sure_var_in_reg(a1, [a0])
-            boxes.append(box)
+            l0 = self._ensure_value_is_boxed(a0, boxes)
+            l1 = self.make_sure_var_in_reg(a1, boxes)
         elif imm_a0 and not imm_a1:
-            l0 = self.make_sure_var_in_reg(a0)
-            l1, box = self._ensure_value_is_boxed(a1, boxes)
-            boxes.append(box)
+            l0 = self.make_sure_var_in_reg(a0, boxes)
+            l1 = self._ensure_value_is_boxed(a1, boxes)
         else:
-            l0, box = self._ensure_value_is_boxed(a0, boxes)
-            boxes.append(box)
-            l1, box = self._ensure_value_is_boxed(a1, boxes)
-            boxes.append(box)
-        return [l0, l1], boxes
+            l0 = self._ensure_value_is_boxed(a0, boxes)
+            l1 = self._ensure_value_is_boxed(a1, boxes)
+        return [l0, l1]
 
     def prepare_op_int_sub(self, op, fcond):
-        locs, boxes = self._prepare_op_int_sub(op, fcond)
-        self.possibly_free_vars(boxes)
+        locs = self._prepare_op_int_sub(op, fcond)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
         return locs + [res]
 
@@ -352,10 +458,8 @@
         boxes = list(op.getarglist())
         a0, a1 = boxes
 
-        reg1, box = self._ensure_value_is_boxed(a0, forbidden_vars=boxes)
-        boxes.append(box)
-        reg2, box = self._ensure_value_is_boxed(a1, forbidden_vars=boxes)
-        boxes.append(box)
+        reg1 = self._ensure_value_is_boxed(a0, forbidden_vars=boxes)
+        reg2 = self._ensure_value_is_boxed(a1, forbidden_vars=boxes)
 
         self.possibly_free_vars(boxes)
         self.possibly_free_vars_for_op(op)
@@ -364,42 +468,23 @@
         return [reg1, reg2, res]
 
     def prepare_guard_int_mul_ovf(self, op, guard, fcond):
-        boxes = list(op.getarglist())
-        a0, a1 = boxes
-
-        reg1, box = self._ensure_value_is_boxed(a0, forbidden_vars=boxes)
-        boxes.append(box)
-        reg2, box = self._ensure_value_is_boxed(a1, forbidden_vars=boxes)
-        boxes.append(box)
+        boxes = op.getarglist()
+        reg1 = self._ensure_value_is_boxed(boxes[0], forbidden_vars=boxes)
+        reg2 = self._ensure_value_is_boxed(boxes[1], forbidden_vars=boxes)
         res = self.force_allocate_reg(op.result)
-        args = self._prepare_guard(guard, [reg1, reg2, res])
-
-        self.possibly_free_vars(boxes)
-        self.possibly_free_vars_for_op(op)
-        self.possibly_free_var(op.result)
-        self.possibly_free_vars(guard.getfailargs())
-        return args
-
+        return self._prepare_guard(guard, [reg1, reg2, res])
 
     def prepare_guard_int_add_ovf(self, op, guard, fcond):
-        locs, boxes = self._prepare_op_int_add(op, fcond)
+        locs = self._prepare_op_int_add(op, fcond)
         res = self.force_allocate_reg(op.result)
         locs.append(res)
-        locs = self._prepare_guard(guard, locs)
-        self.possibly_free_vars(boxes)
-        self.possibly_free_vars_for_op(op)
-        self.possibly_free_vars(guard.getfailargs())
-        return locs
+        return self._prepare_guard(guard, locs)
 
     def prepare_guard_int_sub_ovf(self, op, guard, fcond):
-        locs, boxes = self._prepare_op_int_sub(op, fcond)
+        locs = self._prepare_op_int_sub(op, fcond)
         res = self.force_allocate_reg(op.result)
         locs.append(res)
-        locs = self._prepare_guard(guard, locs)
-        self.possibly_free_vars(boxes)
-        self.possibly_free_vars_for_op(op)
-        self.possibly_free_vars(guard.getfailargs())
-        return locs
+        return self._prepare_guard(guard, locs)
 
     prepare_op_int_floordiv = prepare_op_by_helper_call('int_floordiv')
     prepare_op_int_mod = prepare_op_by_helper_call('int_mod')
@@ -408,9 +493,12 @@
     prepare_op_int_and = prepare_op_ri('int_and')
     prepare_op_int_or = prepare_op_ri('int_or')
     prepare_op_int_xor = prepare_op_ri('int_xor')
-    prepare_op_int_lshift = prepare_op_ri('int_lshift', imm_size=0x1F, allow_zero=False, commutative=False)
-    prepare_op_int_rshift = prepare_op_ri('int_rshift', imm_size=0x1F, allow_zero=False, commutative=False)
-    prepare_op_uint_rshift = prepare_op_ri('uint_rshift', imm_size=0x1F, allow_zero=False, commutative=False)
+    prepare_op_int_lshift = prepare_op_ri('int_lshift', imm_size=0x1F,
+                                        allow_zero=False, commutative=False)
+    prepare_op_int_rshift = prepare_op_ri('int_rshift', imm_size=0x1F,
+                                        allow_zero=False, commutative=False)
+    prepare_op_uint_rshift = prepare_op_ri('uint_rshift', imm_size=0x1F,
+                                        allow_zero=False, commutative=False)
 
     prepare_op_int_lt = prepare_cmp_op('int_lt')
     prepare_op_int_le = prepare_cmp_op('int_le')
@@ -425,8 +513,8 @@
     prepare_op_uint_lt = prepare_cmp_op('uint_lt')
     prepare_op_uint_ge = prepare_cmp_op('uint_ge')
 
-    prepare_op_ptr_eq = prepare_op_int_eq
-    prepare_op_ptr_ne = prepare_op_int_ne
+    prepare_op_ptr_eq = prepare_op_instance_ptr_eq = prepare_op_int_eq
+    prepare_op_ptr_ne = prepare_op_instance_ptr_ne = prepare_op_int_ne
 
     prepare_guard_int_lt = prepare_cmp_op('guard_int_lt')
     prepare_guard_int_le = prepare_cmp_op('guard_int_le')
@@ -441,13 +529,12 @@
     prepare_guard_uint_lt = prepare_cmp_op('guard_uint_lt')
     prepare_guard_uint_ge = prepare_cmp_op('guard_uint_ge')
 
-    prepare_guard_ptr_eq = prepare_guard_int_eq
-    prepare_guard_ptr_ne = prepare_guard_int_ne
+    prepare_guard_ptr_eq = prepare_guard_instance_ptr_eq = prepare_guard_int_eq
+    prepare_guard_ptr_ne = prepare_guard_instance_ptr_ne = prepare_guard_int_ne
 
     prepare_op_int_add_ovf = prepare_op_int_add
     prepare_op_int_sub_ovf = prepare_op_int_sub
 
-
     prepare_op_int_is_true = prepare_op_unary_cmp('int_is_true')
     prepare_op_int_is_zero = prepare_op_unary_cmp('int_is_zero')
 
@@ -455,10 +542,10 @@
     prepare_guard_int_is_zero = prepare_op_unary_cmp('int_is_zero')
 
     def prepare_op_int_neg(self, op, fcond):
-        l0, box = self._ensure_value_is_boxed(op.getarg(0))
-        self.possibly_free_var(box)
+        l0 = self._ensure_value_is_boxed(op.getarg(0))
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         resloc = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
         return [l0, resloc]
 
     prepare_op_int_invert = prepare_op_int_neg
@@ -474,10 +561,14 @@
         args = [imm(rffi.cast(lltype.Signed, op.getarg(0).getint()))]
         return args
 
+    def prepare_op_call_malloc_gc(self, op, fcond):
+        args = [imm(rffi.cast(lltype.Signed, op.getarg(0).getint()))]
+        return args
+
     def _prepare_guard(self, op, args=None):
         if args is None:
             args = []
-        args.append(imm(self.frame_manager.frame_depth))
+        args.append(imm(self.frame_manager.get_frame_depth()))
         for arg in op.getfailargs():
             if arg:
                 args.append(self.loc(arg))
@@ -486,21 +577,19 @@
         return args
 
     def prepare_op_finish(self, op, fcond):
-        args = [imm(self.frame_manager.frame_depth)]
+        args = [None] * (op.numargs() + 1)
         for i in range(op.numargs()):
             arg = op.getarg(i)
             if arg:
-                args.append(self.loc(arg))
+                args[i] = self.loc(arg)
                 self.possibly_free_var(arg)
-            else:
-                args.append(None)
+        n = self.cpu.get_fail_descr_number(op.getdescr())
+        args[-1] = imm(n)
         return args
 
     def prepare_op_guard_true(self, op, fcond):
-        l0, box = self._ensure_value_is_boxed(op.getarg(0))
+        l0 = self._ensure_value_is_boxed(op.getarg(0))
         args = self._prepare_guard(op, [l0])
-        self.possibly_free_var(box)
-        self.possibly_free_vars(op.getfailargs())
         return args
 
     prepare_op_guard_false = prepare_op_guard_true
@@ -510,17 +599,15 @@
     def prepare_op_guard_value(self, op, fcond):
         boxes = list(op.getarglist())
         a0, a1 = boxes
-        imm_a1 = _check_imm_arg(a1)
-        l0, box = self._ensure_value_is_boxed(a0, boxes)
-        boxes.append(box)
+        imm_a1 = check_imm_box(a1)
+        l0 = self._ensure_value_is_boxed(a0, boxes)
         if not imm_a1:
-            l1, box = self._ensure_value_is_boxed(a1,boxes)
-            boxes.append(box)
+            l1 = self._ensure_value_is_boxed(a1, boxes)
         else:
-            l1 = self.make_sure_var_in_reg(a1)
+            l1 = self.make_sure_var_in_reg(a1, boxes)
         assert op.result is None
         arglocs = self._prepare_guard(op, [l0, l1])
-        self.possibly_free_vars(boxes)
+        self.possibly_free_vars(op.getarglist())
         self.possibly_free_vars(op.getfailargs())
         return arglocs
 
@@ -532,33 +619,26 @@
     prepare_op_guard_overflow = prepare_op_guard_no_overflow
     prepare_op_guard_not_invalidated = prepare_op_guard_no_overflow
 
-
     def prepare_op_guard_exception(self, op, fcond):
         boxes = list(op.getarglist())
         arg0 = ConstInt(rffi.cast(lltype.Signed, op.getarg(0).getint()))
-        loc, box = self._ensure_value_is_boxed(arg0)
-        boxes.append(box)
-        box = TempInt()
-        loc1 = self.force_allocate_reg(box, boxes)
-        boxes.append(box)
+        loc = self._ensure_value_is_boxed(arg0)
+        loc1 = self.get_scratch_reg(INT, boxes)
         if op.result in self.longevity:
             resloc = self.force_allocate_reg(op.result, boxes)
-            boxes.append(op.result)
+            self.possibly_free_var(op.result)
         else:
             resloc = None
         pos_exc_value = imm(self.cpu.pos_exc_value())
         pos_exception = imm(self.cpu.pos_exception())
-        arglocs = self._prepare_guard(op, [loc, loc1, resloc, pos_exc_value, pos_exception])
-        self.possibly_free_vars(boxes)
-        self.possibly_free_vars(op.getfailargs())
+        arglocs = self._prepare_guard(op,
+                    [loc, loc1, resloc, pos_exc_value, pos_exception])
         return arglocs
 
     def prepare_op_guard_no_exception(self, op, fcond):
-        loc, box = self._ensure_value_is_boxed(
+        loc = self._ensure_value_is_boxed(
                     ConstInt(self.cpu.pos_exception()))
         arglocs = self._prepare_guard(op, [loc])
-        self.possibly_free_var(box)
-        self.possibly_free_vars(op.getfailargs())
         return arglocs
 
     def prepare_op_guard_class(self, op, fcond):
@@ -570,88 +650,111 @@
         assert isinstance(op.getarg(0), Box)
         boxes = list(op.getarglist())
 
-        x, x_box = self._ensure_value_is_boxed(boxes[0], boxes)
-        boxes.append(x_box)
-
-        t = TempInt()
-        y = self.force_allocate_reg(t, boxes)
-        boxes.append(t)
+        x = self._ensure_value_is_boxed(boxes[0], boxes)
+        y = self.get_scratch_reg(REF, forbidden_vars=boxes)
         y_val = rffi.cast(lltype.Signed, op.getarg(1).getint())
         self.assembler.load(y, imm(y_val))
 
         offset = self.cpu.vtable_offset
         assert offset is not None
-        offset_loc, offset_box = self._ensure_value_is_boxed(ConstInt(offset), boxes)
-        boxes.append(offset_box)
+        offset_loc = self._ensure_value_is_boxed(ConstInt(offset), boxes)
         arglocs = self._prepare_guard(op, [x, y, offset_loc])
-        self.possibly_free_vars(boxes)
-        self.possibly_free_vars(op.getfailargs())
 
         return arglocs
 
+    def compute_hint_frame_locations(self, operations):
+        # optimization only: fill in the 'hint_frame_locations' dictionary
+        # of rm and xrm based on the JUMP at the end of the loop, by looking
+        # at where we would like the boxes to be after the jump.
+        op = operations[-1]
+        if op.getopnum() != rop.JUMP:
+            return
+        self.final_jump_op = op
+        descr = op.getdescr()
+        assert isinstance(descr, TargetToken)
+        if descr._arm_loop_code != 0:
+            # if the target LABEL was already compiled, i.e. if it belongs
+            # to some already-compiled piece of code
+            self._compute_hint_frame_locations_from_descr(descr)
+        #else:
+        #   The loop ends in a JUMP going back to a LABEL in the same loop.
+        #   We cannot fill 'hint_frame_locations' immediately, but we can
+        #   wait until the corresponding prepare_op_label() to know where the
+        #   we would like the boxes to be after the jump.
+
+    def _compute_hint_frame_locations_from_descr(self, descr):
+        arglocs = self.assembler.target_arglocs(descr)
+        jump_op = self.final_jump_op
+        assert len(arglocs) == jump_op.numargs()
+        for i in range(jump_op.numargs()):
+            box = jump_op.getarg(i)
+            if isinstance(box, Box):
+                loc = arglocs[i]
+                if loc is not None and loc.is_stack():
+                    self.frame_manager.hint_frame_locations[box] = loc
 
     def prepare_op_jump(self, op, fcond):
-        assembler = self.assembler
         descr = op.getdescr()
-        assert isinstance(descr, LoopToken)
-        nonfloatlocs, floatlocs = descr._arm_arglocs
+        assert isinstance(descr, TargetToken)
+        self.jump_target_descr = descr
+        arglocs = self.assembler.target_arglocs(descr)
 
         # get temporary locs
         tmploc = r.ip
-        box = TempFloat()
-        # compute 'vfptmploc' to be all_regs[0] by spilling what is there
-        vfptmp = self.vfprm.all_regs[0]
-        vfptmploc = self.vfprm.force_allocate_reg(box, selected_reg=vfptmp)
+        vfptmploc = r.vfp_ip
 
         # Part about non-floats
-        # XXX we don't need a copy, we only just the original list
-        src_locations1 = [self.loc(op.getarg(i)) for i in range(op.numargs())
-                         if op.getarg(i).type != FLOAT]
-        assert tmploc not in nonfloatlocs
-        dst_locations1 = [loc for loc in nonfloatlocs if loc is not None]
+        src_locations1 = []
+        dst_locations1 = []
         # Part about floats
-        src_locations2 = [self.loc(op.getarg(i)) for i in range(op.numargs())
-                         if op.getarg(i).type == FLOAT]
-        dst_locations2 = [loc for loc in floatlocs if loc is not None]
+        src_locations2 = []
+        dst_locations2 = []
+
+        # Build the four lists
+        for i in range(op.numargs()):
+            box = op.getarg(i)
+            src_loc = self.loc(box)
+            dst_loc = arglocs[i]
+            if box.type != FLOAT:
+                src_locations1.append(src_loc)
+                dst_locations1.append(dst_loc)
+            else:
+                src_locations2.append(src_loc)
+                dst_locations2.append(dst_loc)
+
         remap_frame_layout_mixed(self.assembler,
                                  src_locations1, dst_locations1, tmploc,
                                  src_locations2, dst_locations2, vfptmploc)
-        self.possibly_free_var(box)
         return []
 
     def prepare_op_setfield_gc(self, op, fcond):
         boxes = list(op.getarglist())
         a0, a1 = boxes
-        ofs, size, ptr = self._unpack_fielddescr(op.getdescr())
-        base_loc, base_box = self._ensure_value_is_boxed(a0, boxes)
-        boxes.append(base_box)
-        value_loc, value_box = self._ensure_value_is_boxed(a1, boxes)
-        boxes.append(value_box)
-        c_ofs = ConstInt(ofs)
-        if _check_imm_arg(c_ofs):
+        ofs, size, sign = unpack_fielddescr(op.getdescr())
+        base_loc = self._ensure_value_is_boxed(a0, boxes)
+        value_loc = self._ensure_value_is_boxed(a1, boxes)
+        if check_imm_arg(ofs):
             ofs_loc = imm(ofs)
         else:
-            ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, boxes)
-            boxes.append(ofs_box)
-        self.possibly_free_vars(boxes)
+            ofs_loc = self.get_scratch_reg(INT, boxes)
+            self.assembler.load(ofs_loc, imm(ofs))
         return [value_loc, base_loc, ofs_loc, imm(size)]
 
     prepare_op_setfield_raw = prepare_op_setfield_gc
 
     def prepare_op_getfield_gc(self, op, fcond):
         a0 = op.getarg(0)
-        ofs, size, ptr = self._unpack_fielddescr(op.getdescr())
-        base_loc, base_box = self._ensure_value_is_boxed(a0)
-        c_ofs = ConstInt(ofs)
-        if _check_imm_arg(c_ofs):
-            ofs_loc = imm(ofs)
+        ofs, size, sign = unpack_fielddescr(op.getdescr())
+        base_loc = self._ensure_value_is_boxed(a0)
+        immofs = imm(ofs)
+        if check_imm_arg(ofs):
+            ofs_loc = immofs
         else:
-            ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, [base_box])
-            self.possibly_free_var(ofs_box)
-        self.possibly_free_var(a0)
-        self.possibly_free_var(base_box)
+            ofs_loc = self.get_scratch_reg(INT, [a0])
+            self.assembler.load(ofs_loc, immofs)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
         return [base_loc, ofs_loc, res, imm(size)]
 
     prepare_op_getfield_raw = prepare_op_getfield_gc
@@ -659,126 +762,110 @@
     prepare_op_getfield_gc_pure = prepare_op_getfield_gc
 
     def prepare_op_getinteriorfield_gc(self, op, fcond):
-        t = self._unpack_interiorfielddescr(op.getdescr())
+        t = unpack_interiorfielddescr(op.getdescr())
         ofs, itemsize, fieldsize, sign = t
         args = op.getarglist()
-        base_loc, base_box = self._ensure_value_is_boxed(op.getarg(0), args)
-        index_loc, index_box = self._ensure_value_is_boxed(op.getarg(1), args)
-        c_ofs = ConstInt(ofs)
-        if _check_imm_arg(c_ofs):
-            ofs_loc = imm(ofs)
+        base_loc = self._ensure_value_is_boxed(op.getarg(0), args)
+        index_loc = self._ensure_value_is_boxed(op.getarg(1), args)
+        immofs = imm(ofs)
+        if check_imm_arg(ofs):
+            ofs_loc = immofs
         else:
-            ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, [base_box, index_box])
-            self.possibly_free_var(ofs_box)
-        self.possibly_free_vars(args)
-        self.possibly_free_var(base_box)
-        self.possibly_free_var(index_box)
+            ofs_loc = self.get_scratch_reg(INT, args)
+            self.assembler.load(ofs_loc, immofs)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         result_loc = self.force_allocate_reg(op.result)
-        return [base_loc, index_loc, result_loc, ofs_loc, imm(ofs), 
-                                        imm(itemsize), imm(fieldsize)]
+        return [base_loc, index_loc, result_loc, ofs_loc, imm(ofs),
+                                    imm(itemsize), imm(fieldsize)]
 
-    
     def prepare_op_setinteriorfield_gc(self, op, fcond):
-        t = self._unpack_interiorfielddescr(op.getdescr())
+        t = unpack_interiorfielddescr(op.getdescr())
         ofs, itemsize, fieldsize, sign = t
-        boxes = [None]*3
-        base_loc, base_box = self._ensure_value_is_boxed(op.getarg(0), boxes)
-        boxes[0] = base_box
-        index_loc, index_box = self._ensure_value_is_boxed(op.getarg(1), boxes)
-        boxes[1] = index_box
-        value_loc, value_box = self._ensure_value_is_boxed(op.getarg(2), boxes)
-        boxes[2] = value_box
-        c_ofs = ConstInt(ofs)
-        if _check_imm_arg(c_ofs):
-            ofs_loc = imm(ofs)
+        args = op.getarglist()
+        base_loc = self._ensure_value_is_boxed(op.getarg(0), args)
+        index_loc = self._ensure_value_is_boxed(op.getarg(1), args)
+        value_loc = self._ensure_value_is_boxed(op.getarg(2), args)
+        immofs = imm(ofs)
+        if check_imm_arg(ofs):
+            ofs_loc = immofs
         else:
-            ofs_loc, ofs_box = self._ensure_value_is_boxed(c_ofs, boxes)
-            self.possibly_free_var(ofs_box)
-        self.possibly_free_vars(boxes)
+            ofs_loc = self.get_scratch_reg(INT, args)
+            self.assembler.load(ofs_loc, immofs)
         return [base_loc, index_loc, value_loc, ofs_loc, imm(ofs),
                                         imm(itemsize), imm(fieldsize)]
 
     def prepare_op_arraylen_gc(self, op, fcond):
         arraydescr = op.getdescr()
-        assert isinstance(arraydescr, BaseArrayDescr)
-        ofs = arraydescr.get_ofs_length(self.cpu.translate_support_code)
+        assert isinstance(arraydescr, ArrayDescr)
+        ofs = arraydescr.lendescr.offset
         arg = op.getarg(0)
-        base_loc, base_box = self._ensure_value_is_boxed(arg)
-        self.possibly_free_vars([arg, base_box])
-
+        base_loc = self._ensure_value_is_boxed(arg)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
         return [res, base_loc, imm(ofs)]
 
     def prepare_op_setarrayitem_gc(self, op, fcond):
-        a0, a1, a2 = boxes = list(op.getarglist())
-        _, scale, base_ofs, _, ptr = self._unpack_arraydescr(op.getdescr())
-
-        base_loc, base_box  = self._ensure_value_is_boxed(a0, boxes)
-        boxes.append(base_box)
-        ofs_loc, ofs_box = self._ensure_value_is_boxed(a1, boxes)
-        boxes.append(ofs_box)
-        value_loc, value_box = self._ensure_value_is_boxed(a2, boxes)
-        boxes.append(value_box)
-        self.possibly_free_vars(boxes)
-        assert _check_imm_arg(ConstInt(base_ofs))
-        return [value_loc, base_loc, ofs_loc, imm(scale), imm(base_ofs)]
+        a0, a1, a2 = list(op.getarglist())
+        size, ofs, _ = unpack_arraydescr(op.getdescr())
+        scale = get_scale(size)
+        args = op.getarglist()
+        base_loc = self._ensure_value_is_boxed(a0, args)
+        ofs_loc = self._ensure_value_is_boxed(a1, args)
+        value_loc = self._ensure_value_is_boxed(a2, args)
+        assert check_imm_arg(ofs)
+        return [value_loc, base_loc, ofs_loc, imm(scale), imm(ofs)]
     prepare_op_setarrayitem_raw = prepare_op_setarrayitem_gc
 
     def prepare_op_getarrayitem_gc(self, op, fcond):
         a0, a1 = boxes = list(op.getarglist())
-        _, scale, base_ofs, _, ptr = self._unpack_arraydescr(op.getdescr())
-
-        base_loc, base_box  = self._ensure_value_is_boxed(a0, boxes)
-        boxes.append(base_box)
-        ofs_loc, ofs_box = self._ensure_value_is_boxed(a1, boxes)
-        boxes.append(ofs_box)
-        self.possibly_free_vars(boxes)
+        size, ofs, _ = unpack_arraydescr(op.getdescr())
+        scale = get_scale(size)
+        base_loc = self._ensure_value_is_boxed(a0, boxes)
+        ofs_loc = self._ensure_value_is_boxed(a1, boxes)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
-        assert _check_imm_arg(ConstInt(base_ofs))
-        return [res, base_loc, ofs_loc, imm(scale), imm(base_ofs)]
+        assert check_imm_arg(ofs)
+        return [res, base_loc, ofs_loc, imm(scale), imm(ofs)]
 
     prepare_op_getarrayitem_raw = prepare_op_getarrayitem_gc
     prepare_op_getarrayitem_gc_pure = prepare_op_getarrayitem_gc
 
     def prepare_op_strlen(self, op, fcond):
-        l0, box = self._ensure_value_is_boxed(op.getarg(0))
-        boxes = [box]
-
-
+        args = op.getarglist()
+        l0 = self._ensure_value_is_boxed(op.getarg(0))
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
                                          self.cpu.translate_support_code)
-        ofs_box = ConstInt(ofs_length)
-        imm_ofs = _check_imm_arg(ofs_box)
+        immofs = imm(ofs_length)
+        if check_imm_arg(ofs_length):
+            l1 = immofs
+        else:
+            l1 = self.get_scratch_reg(INT, args)
+            self.assembler.load(l1, immofs)
 
-        if imm_ofs:
-            l1 = self.make_sure_var_in_reg(ofs_box, boxes)
-        else:
-            l1, box1 = self._ensure_value_is_boxed(ofs_box, boxes)
-            boxes.append(box1)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
 
-        self.possibly_free_vars(boxes)
         res = self.force_allocate_reg(op.result)
         self.possibly_free_var(op.result)
         return [l0, l1, res]
 
     def prepare_op_strgetitem(self, op, fcond):
         boxes = list(op.getarglist())
-        base_loc, box = self._ensure_value_is_boxed(boxes[0])
-        boxes.append(box)
+        base_loc = self._ensure_value_is_boxed(boxes[0])
 
         a1 = boxes[1]
-        imm_a1 = _check_imm_arg(a1)
+        imm_a1 = check_imm_box(a1)
         if imm_a1:
             ofs_loc = self.make_sure_var_in_reg(a1, boxes)
         else:
-            ofs_loc, box = self._ensure_value_is_boxed(a1, boxes)
-            boxes.append(box)
+            ofs_loc = self._ensure_value_is_boxed(a1, boxes)
 
-        self.possibly_free_vars(boxes)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
                                          self.cpu.translate_support_code)
@@ -787,18 +874,9 @@
 
     def prepare_op_strsetitem(self, op, fcond):
         boxes = list(op.getarglist())
-
-        base_loc, box = self._ensure_value_is_boxed(boxes[0], boxes)
-        boxes.append(box)
-
-        ofs_loc, box = self._ensure_value_is_boxed(boxes[1], boxes)
-        boxes.append(box)
-
-        value_loc, box = self._ensure_value_is_boxed(boxes[2], boxes)
-        boxes.append(box)
-
-        self.possibly_free_vars(boxes)
-
+        base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
+        ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
+        value_loc = self._ensure_value_is_boxed(boxes[2], boxes)
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.STR,
                                          self.cpu.translate_support_code)
         assert itemsize == 1
@@ -808,156 +886,86 @@
     prepare_op_copyunicodecontent = void
 
     def prepare_op_unicodelen(self, op, fcond):
-        l0, box = self._ensure_value_is_boxed(op.getarg(0))
-        boxes = [box]
+        l0 = self._ensure_value_is_boxed(op.getarg(0))
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
                                          self.cpu.translate_support_code)
-        ofs_box = ConstInt(ofs_length)
-        imm_ofs = _check_imm_arg(ofs_box)
+        immofs = imm(ofs_length)
+        if check_imm_arg(ofs_length):
+            l1 = immofs
+        else:
+            l1 = self.get_scratch_reg(INT, [op.getarg(0)])
+            self.assembler.load(l1, immofs)
 
-        if imm_ofs:
-            l1 = imm(ofs_length)
-        else:
-            l1, box1 = self._ensure_value_is_boxed(ofs_box, boxes)
-            boxes.append(box1)
-
-        self.possibly_free_vars(boxes)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
         return [l0, l1, res]
 
     def prepare_op_unicodegetitem(self, op, fcond):
         boxes = list(op.getarglist())
-        base_loc, box = self._ensure_value_is_boxed(boxes[0], boxes)
-        boxes.append(box)
-        ofs_loc, box = self._ensure_value_is_boxed(boxes[1], boxes)
-        boxes.append(box)
-        self.possibly_free_vars(boxes)
+        base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
+        ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
 
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
 
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
                                          self.cpu.translate_support_code)
-        scale = itemsize/2
-        return [res, base_loc, ofs_loc, imm(scale), imm(basesize), imm(itemsize)]
+        scale = itemsize / 2
+        return [res, base_loc, ofs_loc,
+            imm(scale), imm(basesize), imm(itemsize)]
 
     def prepare_op_unicodesetitem(self, op, fcond):
         boxes = list(op.getarglist())
-        base_loc, box = self._ensure_value_is_boxed(boxes[0], boxes)
-        boxes.append(box)
-        ofs_loc, box = self._ensure_value_is_boxed(boxes[1], boxes)
-        boxes.append(box)
-        value_loc, box = self._ensure_value_is_boxed(boxes[2], boxes)
-        boxes.append(box)
-
-        self.possibly_free_vars(boxes)
-
+        base_loc = self._ensure_value_is_boxed(boxes[0], boxes)
+        ofs_loc = self._ensure_value_is_boxed(boxes[1], boxes)
+        value_loc = self._ensure_value_is_boxed(boxes[2], boxes)
         basesize, itemsize, ofs_length = symbolic.get_array_token(rstr.UNICODE,
                                          self.cpu.translate_support_code)
-        scale = itemsize/2
-        return [value_loc, base_loc, ofs_loc, imm(scale), imm(basesize), imm(itemsize)]
+        scale = itemsize / 2
+        return [value_loc, base_loc, ofs_loc,
+            imm(scale), imm(basesize), imm(itemsize)]
 
     def prepare_op_same_as(self, op, fcond):
         arg = op.getarg(0)
-        imm_arg = _check_imm_arg(arg)
+        imm_arg = check_imm_box(arg)
         if imm_arg:
             argloc = self.make_sure_var_in_reg(arg)
         else:
-            argloc, box = self._ensure_value_is_boxed(arg)
-            self.possibly_free_var(box)
+            argloc = self._ensure_value_is_boxed(arg)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
+        resloc = self.force_allocate_reg(op.result)
+        return [argloc, resloc]
 
-        resloc = self.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
-        return [argloc, resloc]
     prepare_op_cast_ptr_to_int = prepare_op_same_as
     prepare_op_cast_int_to_ptr = prepare_op_same_as
 
-    def prepare_op_new(self, op, fcond):
-        gc_ll_descr = self.assembler.cpu.gc_ll_descr
-        if gc_ll_descr.can_inline_malloc(op.getdescr()):
-            self.fastpath_malloc_fixedsize(op, op.getdescr())
-        else:
-            arglocs = self._prepare_args_for_new_op(op.getdescr())
-            force_index = self.assembler.write_new_force_index()
-            self.assembler._emit_call(force_index, self.assembler.malloc_func_addr,
-                                    arglocs, self, fcond, result=op.result)
-            self.possibly_free_vars(arglocs)
-        self.possibly_free_var(op.result)
-        return []
+    def prepare_op_call_malloc_nursery(self, op, fcond):
+        size_box = op.getarg(0)
+        assert isinstance(size_box, ConstInt)
+        size = size_box.getint()
 
-    def prepare_op_new_with_vtable(self, op, fcond):
-        classint = op.getarg(0).getint()
-        descrsize = heaptracker.vtable2descr(self.cpu, classint)
-        if self.assembler.cpu.gc_ll_descr.can_inline_malloc(descrsize):
-            self.fastpath_malloc_fixedsize(op, descrsize)
-        else:
-            callargs = self._prepare_args_for_new_op(descrsize)
-            force_index = self.assembler.write_new_force_index()
-            self.assembler._emit_call(force_index, self.assembler.malloc_func_addr,
-                                        callargs, self, fcond, result=op.result)
-            self.possibly_free_vars(callargs)
-        self.possibly_free_var(op.result)
-        return [imm(classint)]
-
-    def prepare_op_new_array(self, op, fcond):
-        gc_ll_descr = self.cpu.gc_ll_descr
-        if gc_ll_descr.get_funcptr_for_newarray is not None:
-            # framework GC
-            box_num_elem = op.getarg(0)
-            if isinstance(box_num_elem, ConstInt):
-                num_elem = box_num_elem.value
-                if gc_ll_descr.can_inline_malloc_varsize(op.getdescr(),
-                                                         num_elem):
-                    self.fastpath_malloc_varsize(op, op.getdescr(), num_elem)
-                    return []
-            args = self.assembler.cpu.gc_ll_descr.args_for_new_array(
-                op.getdescr())
-            argboxes = [ConstInt(x) for x in args]
-            argboxes.append(box_num_elem)
-            force_index = self.assembler.write_new_force_index()
-            self.assembler._emit_call(force_index, self.assembler.malloc_array_func_addr,
-                                        argboxes, self, fcond, result=op.result)
-            return []
-        # boehm GC
-        itemsize, scale, basesize, ofs_length, _ = (
-            self._unpack_arraydescr(op.getdescr()))
-        return self._malloc_varsize(basesize, ofs_length, itemsize, op)
-
-    def fastpath_malloc_varsize(self, op, arraydescr, num_elem):
-        assert isinstance(arraydescr, BaseArrayDescr)
-        ofs_length = arraydescr.get_ofs_length(self.cpu.translate_support_code)
-        basesize = arraydescr.get_base_size(self.cpu.translate_support_code)
-        itemsize = arraydescr.get_item_size(self.cpu.translate_support_code)
-        size = basesize + itemsize * num_elem
-        self._do_fastpath_malloc(op, size, arraydescr.tid)
-        # we know the resullt of the malloc call is in r0
-        self.assembler.set_new_array_length(r.r0, ofs_length, num_elem)
-
-    def fastpath_malloc_fixedsize(self, op, descr):
-        assert isinstance(descr, BaseSizeDescr)
-        self._do_fastpath_malloc(op, descr.size, descr.tid)
-
-    def _do_fastpath_malloc(self, op, size, tid):
-        gc_ll_descr = self.assembler.cpu.gc_ll_descr
         self.rm.force_allocate_reg(op.result, selected_reg=r.r0)
         t = TempInt()
         self.rm.force_allocate_reg(t, selected_reg=r.r1)
         self.possibly_free_var(op.result)
         self.possibly_free_var(t)
 
+        gc_ll_descr = self.assembler.cpu.gc_ll_descr
         self.assembler.malloc_cond(
             gc_ll_descr.get_nursery_free_addr(),
             gc_ll_descr.get_nursery_top_addr(),
-            size, tid,
+            size
             )
 
     def get_mark_gc_roots(self, gcrootmap, use_copy_area=False):
         shape = gcrootmap.get_basic_shape(False)
-        for v, val in self.frame_manager.frame_bindings.items():
+        for v, val in self.frame_manager.bindings.items():
             if (isinstance(v, BoxPtr) and self.rm.stays_alive(v)):
                 assert val.is_stack()
-                gcrootmap.add_frame_offset(shape, val.position*-WORD)
+                gcrootmap.add_frame_offset(shape, val.position * -WORD)
         for v, reg in self.rm.reg_bindings.items():
             if reg is r.r0:
                 continue
@@ -970,59 +978,6 @@
                     assert 0, 'sure??'
         return gcrootmap.compress_callshape(shape,
                                             self.assembler.datablockwrapper)
-    def prepare_op_newstr(self, op, fcond):
-        gc_ll_descr = self.cpu.gc_ll_descr
-        if gc_ll_descr.get_funcptr_for_newstr is not None:
-            force_index = self.assembler.write_new_force_index()
-            self.assembler._emit_call(force_index,
-                    self.assembler.malloc_str_func_addr, [op.getarg(0)],
-                    self, fcond, op.result)
-            return []
-        # boehm GC
-        ofs_items, itemsize, ofs = symbolic.get_array_token(rstr.STR,
-                            self.cpu.translate_support_code)
-        assert itemsize == 1
-        return self._malloc_varsize(ofs_items, ofs, itemsize, op)
-
-    def prepare_op_newunicode(self, op, fcond):
-        gc_ll_descr = self.cpu.gc_ll_descr
-        if gc_ll_descr.get_funcptr_for_newunicode is not None:
-            force_index = self.assembler.write_new_force_index()
-            self.assembler._emit_call(force_index, self.assembler.malloc_unicode_func_addr,
-                                    [op.getarg(0)], self, fcond, op.result)
-            return []
-        # boehm GC
-        ofs_items, _, ofs = symbolic.get_array_token(rstr.UNICODE,
-                            self.cpu.translate_support_code)
-        _, itemsize, _ = symbolic.get_array_token(rstr.UNICODE,
-                            self.cpu.translate_support_code)
-        return self._malloc_varsize(ofs_items, ofs, itemsize, op)
-
-    def _malloc_varsize(self, ofs_items, ofs_length, itemsize, op):
-        v = op.getarg(0)
-        res_v = op.result
-        boxes = [v, res_v]
-        itemsize_box = ConstInt(itemsize)
-        ofs_items_box = ConstInt(ofs_items)
-        if _check_imm_arg(ofs_items_box):
-            ofs_items_loc = self.convert_to_imm(ofs_items_box)
-        else:
-            ofs_items_loc, ofs_items_box = self._ensure_value_is_boxed(ofs_items_box, boxes)
-            boxes.append(ofs_items_box)
-        vloc, vbox = self._ensure_value_is_boxed(v, [res_v])
-        boxes.append(vbox)
-        size, size_box = self._ensure_value_is_boxed(itemsize_box, boxes)
-        boxes.append(size_box)
-        self.assembler._regalloc_malloc_varsize(size, size_box,
-                                vloc, vbox, ofs_items_loc, self, res_v)
-        base_loc = self.make_sure_var_in_reg(res_v)
-
-        value_loc, vbox = self._ensure_value_is_boxed(v, [res_v])
-        boxes.append(vbox)
-        self.possibly_free_vars(boxes)
-        assert value_loc.is_reg()
-        assert base_loc.is_reg()
-        return [value_loc, base_loc, imm(ofs_length)]
 
     prepare_op_debug_merge_point = void
     prepare_op_jit_debug = void
@@ -1034,12 +989,10 @@
         # because it will be needed anyway by the following setfield_gc
         # or setarrayitem_gc. It avoids loading it twice from the memory.
         arglocs = []
-        argboxes = []
+        args = op.getarglist()
         for i in range(N):
-            loc, box = self._ensure_value_is_boxed(op.getarg(i), argboxes)
+            loc = self._ensure_value_is_boxed(op.getarg(i), args)
             arglocs.append(loc)
-            argboxes.append(box)
-        self.rm.possibly_free_vars(argboxes)
         return arglocs
 
     prepare_op_cond_call_gc_wb_array = prepare_op_cond_call_gc_wb
@@ -1049,6 +1002,46 @@
         self.possibly_free_var(op.result)
         return [res_loc]
 
+    def prepare_op_label(self, op, fcond):
+        # XXX big refactoring needed?
+        descr = op.getdescr()
+        assert isinstance(descr, TargetToken)
+        inputargs = op.getarglist()
+        arglocs = [None] * len(inputargs)
+        #
+        # we use force_spill() on the boxes that are not going to be really
+        # used any more in the loop, but that are kept alive anyway
+        # by being in a next LABEL's or a JUMP's argument or fail_args
+        # of some guard
+        position = self.rm.position
+        for arg in inputargs:
+            assert isinstance(arg, Box)
+            if self.last_real_usage.get(arg, -1) <= position:
+                self.force_spill_var(arg)
+
+        #
+        for i in range(len(inputargs)):
+            arg = inputargs[i]
+            assert isinstance(arg, Box)
+            loc = self.loc(arg)
+            arglocs[i] = loc
+            if loc.is_reg():
+                self.frame_manager.mark_as_free(arg)
+        #
+        descr._arm_arglocs = arglocs
+        descr._arm_loop_code = self.assembler.mc.currpos()
+        descr._arm_clt = self.assembler.current_clt
+        self.assembler.target_tokens_currently_compiling[descr] = None
+        self.possibly_free_vars_for_op(op)
+        #
+        # if the LABEL's descr is precisely the target of the JUMP at the
+        # end of the same loop, i.e. if what we are compiling is a single
+        # loop that ends up jumping to this LABEL, then we can now provide
+        # the hints about the expected position of the spilled variables.
+        jump_op = self.final_jump_op
+        if jump_op is not None and jump_op.getdescr() is descr:
+            self._compute_hint_frame_locations_from_descr(descr)
+
     def prepare_guard_call_may_force(self, op, guard_op, fcond):
         faildescr = guard_op.getdescr()
         fail_index = self.cpu.get_fail_descr_number(faildescr)
@@ -1067,13 +1060,11 @@
         gcrootmap = self.cpu.gc_ll_descr.gcrootmap
         if gcrootmap:
             arglocs = []
-            argboxes = []
+            args = op.getarglist()
             for i in range(op.numargs()):
-                loc, box = self._ensure_value_is_boxed(op.getarg(i), argboxes)
+                loc = self._ensure_value_is_boxed(op.getarg(i), args)
                 arglocs.append(loc)
-                argboxes.append(box)
             self.assembler.call_release_gil(gcrootmap, arglocs, fcond)
-            self.possibly_free_vars(argboxes)
         # do the call
         faildescr = guard_op.getdescr()
         fail_index = self.cpu.get_fail_descr_number(faildescr)
@@ -1081,17 +1072,20 @@
         self.assembler.emit_op_call(op, args, self, fcond, fail_index)
         # then reopen the stack
         if gcrootmap:
-            self.assembler.call_reacquire_gil(gcrootmap, r.r0, fcond)
+            if op.result:
+                result_loc = self.call_result_location(op.result)
+            else:
+                result_loc = None
+            self.assembler.call_reacquire_gil(gcrootmap, result_loc, fcond)
         locs = self._prepare_guard(guard_op)
-        self.possibly_free_vars(guard_op.getfailargs())
         return locs
 
     def prepare_guard_call_assembler(self, op, guard_op, fcond):
         descr = op.getdescr()
-        assert isinstance(descr, LoopToken)
+        assert isinstance(descr, JitCellToken)
         jd = descr.outermost_jitdriver_sd
         assert jd is not None
-        size = jd.portal_calldescr.get_result_size(self.cpu.translate_support_code)
+        size = jd.portal_calldescr.get_result_size()
         vable_index = jd.index_of_virtualizable
         if vable_index >= 0:
             self._sync_var(op.getarg(vable_index))
@@ -1113,117 +1107,92 @@
             arglocs.append(t)
         return arglocs
 
-    # from ../x86/regalloc.py:791
-    def _unpack_fielddescr(self, fielddescr):
-        assert isinstance(fielddescr, BaseFieldDescr)
-        ofs = fielddescr.offset
-        size = fielddescr.get_field_size(self.cpu.translate_support_code)
-        ptr = fielddescr.is_pointer_field()
-        return ofs, size, ptr
-
-    # from ../x86/regalloc.py:779
-    def _unpack_arraydescr(self, arraydescr):
-        assert isinstance(arraydescr, BaseArrayDescr)
-        cpu = self.cpu
-        ofs_length = arraydescr.get_ofs_length(cpu.translate_support_code)
-        ofs = arraydescr.get_base_size(cpu.translate_support_code)
-        size = arraydescr.get_item_size(cpu.translate_support_code)
-        ptr = arraydescr.is_array_of_pointers()
-        scale = 0
-        while (1 << scale) < size:
-            scale += 1
-        assert (1 << scale) == size
-        return size, scale, ofs, ofs_length, ptr
-
-    # from ../x86/regalloc.py:965
-    def _unpack_interiorfielddescr(self, descr):
-        assert isinstance(descr, InteriorFieldDescr)
-        arraydescr = descr.arraydescr
-        ofs = arraydescr.get_base_size(self.cpu.translate_support_code)
-        itemsize = arraydescr.get_item_size(self.cpu.translate_support_code)
-        fieldsize = descr.fielddescr.get_field_size(self.cpu.translate_support_code)
-        sign = descr.fielddescr.is_field_signed()
-        ofs += descr.fielddescr.offset
-        return ofs, itemsize, fieldsize, sign
-
     prepare_op_float_add = prepare_float_op(name='prepare_op_float_add')
     prepare_op_float_sub = prepare_float_op(name='prepare_op_float_sub')
     prepare_op_float_mul = prepare_float_op(name='prepare_op_float_mul')
-    prepare_op_float_truediv = prepare_float_op(name='prepare_op_float_truediv')
-    prepare_op_float_lt = prepare_float_op(float_result=False, name='prepare_op_float_lt')
-    prepare_op_float_le = prepare_float_op(float_result=False, name='prepare_op_float_le')
-    prepare_op_float_eq = prepare_float_op(float_result=False, name='prepare_op_float_eq')
-    prepare_op_float_ne = prepare_float_op(float_result=False, name='prepare_op_float_ne')
-    prepare_op_float_gt = prepare_float_op(float_result=False, name='prepare_op_float_gt')
-    prepare_op_float_ge = prepare_float_op(float_result=False, name='prepare_op_float_ge')
-    prepare_op_float_neg = prepare_float_op(base=False, name='prepare_op_float_neg')
-    prepare_op_float_abs = prepare_float_op(base=False, name='prepare_op_float_abs')
+    prepare_op_float_truediv = prepare_float_op(
+                                            name='prepare_op_float_truediv')
+    prepare_op_float_lt = prepare_float_op(float_result=False,
+                                            name='prepare_op_float_lt')
+    prepare_op_float_le = prepare_float_op(float_result=False,
+                                            name='prepare_op_float_le')
+    prepare_op_float_eq = prepare_float_op(float_result=False,
+                                            name='prepare_op_float_eq')
+    prepare_op_float_ne = prepare_float_op(float_result=False,
+                                            name='prepare_op_float_ne')
+    prepare_op_float_gt = prepare_float_op(float_result=False,
+                                            name='prepare_op_float_gt')
+    prepare_op_float_ge = prepare_float_op(float_result=False,
+                                            name='prepare_op_float_ge')
+    prepare_op_float_neg = prepare_float_op(base=False,
+                                            name='prepare_op_float_neg')
+    prepare_op_float_abs = prepare_float_op(base=False,
+                                            name='prepare_op_float_abs')
 
-    prepare_guard_float_lt = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_lt')
-    prepare_guard_float_le = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_le')
-    prepare_guard_float_eq = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_eq')
-    prepare_guard_float_ne = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_ne')
-    prepare_guard_float_gt = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_gt')
-    prepare_guard_float_ge = prepare_float_op(guard=True, float_result=False, name='prepare_guard_float_ge')
+    prepare_guard_float_lt = prepare_float_op(guard=True,
+                            float_result=False, name='prepare_guard_float_lt')
+    prepare_guard_float_le = prepare_float_op(guard=True,
+                            float_result=False, name='prepare_guard_float_le')
+    prepare_guard_float_eq = prepare_float_op(guard=True,
+                            float_result=False, name='prepare_guard_float_eq')
+    prepare_guard_float_ne = prepare_float_op(guard=True,
+                            float_result=False, name='prepare_guard_float_ne')
+    prepare_guard_float_gt = prepare_float_op(guard=True,
+                            float_result=False, name='prepare_guard_float_gt')
+    prepare_guard_float_ge = prepare_float_op(guard=True,
+                            float_result=False, name='prepare_guard_float_ge')
 
     def prepare_op_math_sqrt(self, op, fcond):
-        loc, box = self._ensure_value_is_boxed(op.getarg(1))
-        self.possibly_free_var(box)
+        loc = self._ensure_value_is_boxed(op.getarg(1))
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
         res = self.vfprm.force_allocate_reg(op.result)
         self.possibly_free_var(op.result)
         return [loc, res]
 
     def prepare_op_cast_float_to_int(self, op, fcond):
-        locs = []
-
-        loc1, box1 = self._ensure_value_is_boxed(op.getarg(0))
-        locs.append(loc1)
-        self.possibly_free_var(box1)
-
-        t = TempFloat()
-        temp_loc = self.vfprm.force_allocate_reg(t)
-        locs.append(temp_loc)
-        self.possibly_free_var(t)
-
-        res  = self.rm.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
-        locs.append(res)
-
-        return locs
+        loc1 = self._ensure_value_is_boxed(op.getarg(0))
+        temp_loc = self.get_scratch_reg(FLOAT)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
+        res = self.rm.force_allocate_reg(op.result)
+        return [loc1, temp_loc, res]
 
     def prepare_op_cast_int_to_float(self, op, fcond):
-        locs = []
-
-        loc1, box1 = self._ensure_value_is_boxed(op.getarg(0))
-        locs.append(loc1)
-        self.possibly_free_var(box1)
-
-        t = TempFloat()
-        temp_loc = self.vfprm.force_allocate_reg(t)
-        locs.append(temp_loc)
-        self.possibly_free_var(t)
-
-        res  = self.vfprm.force_allocate_reg(op.result)
-        self.possibly_free_var(op.result)
-        locs.append(res)
-
-        return locs
+        loc1 = self._ensure_value_is_boxed(op.getarg(0))
+        temp_loc = self.get_scratch_reg(FLOAT)
+        self.possibly_free_vars_for_op(op)
+        self.free_temp_vars()
+        res = self.vfprm.force_allocate_reg(op.result)
+        return [loc1, temp_loc, res]
 
     def prepare_force_spill(self, op, fcond):
         self.force_spill_var(op.getarg(0))
         return []
 
+
 def add_none_argument(fn):
     return lambda self, op, fcond: fn(self, op, None, fcond)
 
+
 def notimplemented(self, op, fcond):
-    raise NotImplementedError, op
+    raise NotImplementedError(op)
+
+
 def notimplemented_with_guard(self, op, guard_op, fcond):
-    raise NotImplementedError, op
+    raise NotImplementedError(op)
 
 operations = [notimplemented] * (rop._LAST + 1)
 operations_with_guard = [notimplemented_with_guard] * (rop._LAST + 1)
 
+
+def get_scale(size):
+    scale = 0
+    while (1 << scale) < size:
+        scale += 1
+    assert (1 << scale) == size
+    return scale
+
 for key, value in rop.__dict__.items():
     key = key.lower()
     if key.startswith('_'):
diff --git a/pypy/jit/backend/arm/registers.py b/pypy/jit/backend/arm/registers.py
--- a/pypy/jit/backend/arm/registers.py
+++ b/pypy/jit/backend/arm/registers.py
@@ -1,11 +1,14 @@
-from pypy.jit.backend.arm.locations import RegisterLocation, VFPRegisterLocation
+from pypy.jit.backend.arm.locations import VFPRegisterLocation
+from pypy.jit.backend.arm.locations import RegisterLocation
 
 registers = [RegisterLocation(i) for i in range(16)]
 vfpregisters = [VFPRegisterLocation(i) for i in range(16)]
-r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15 = registers
+[r0, r1, r2, r3, r4, r5, r6, r7,
+    r8, r9, r10, r11, r12, r13, r14, r15] = registers
 
 #vfp registers interpreted as 64-bit registers
-d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15 = vfpregisters
+[d0, d1, d2, d3, d4, d5, d6, d7,
+    d8, d9, d10, d11, d12, d13, d14, d15] = vfpregisters
 
 # aliases for registers
 fp = r11
@@ -18,13 +21,12 @@
 all_regs = [r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10]
 all_vfp_regs = vfpregisters[:-1]
 
-caller_resp = [r0, r1, r2, r3]
+argument_regs = caller_resp = [r0, r1, r2, r3]
 callee_resp = [r4, r5, r6, r7, r8, r9, r10, fp]
-callee_saved_registers = callee_resp+[lr]
-callee_restored_registers = callee_resp+[pc]
+callee_saved_registers = callee_resp + [lr]
+callee_restored_registers = callee_resp + [pc]
 
 caller_vfp_resp = [d0, d1, d2, d3, d4, d5, d6, d7]
 callee_vfp_resp = [d8, d9, d10, d11, d12, d13, d14, d15]
 
 callee_saved_vfp_registers = callee_vfp_resp
-
diff --git a/pypy/jit/backend/arm/runner.py b/pypy/jit/backend/arm/runner.py
--- a/pypy/jit/backend/arm/runner.py
+++ b/pypy/jit/backend/arm/runner.py
@@ -9,21 +9,24 @@
 
 class ArmCPU(AbstractLLCPU):
 
-    BOOTSTRAP_TP = lltype.FuncType([], lltype.Signed)
     supports_floats = True
 
     def __init__(self, rtyper, stats, opts=None, translate_support_code=False,
                  gcdescr=None):
         if gcdescr is not None:
             gcdescr.force_index_ofs = FORCE_INDEX_OFS
+            # XXX for now the arm backend does not support the gcremovetypeptr
+            # translation option
+            assert gcdescr.config.translation.gcremovetypeptr is False
         AbstractLLCPU.__init__(self, rtyper, stats, opts,
                                translate_support_code, gcdescr)
+
     def setup(self):
         if self.opts is not None:
             failargs_limit = self.opts.failargs_limit
         else:
             failargs_limit = 1000
-        self.assembler = AssemblerARM(self)
+        self.assembler = AssemblerARM(self, failargs_limit=failargs_limit)
 
     def setup_once(self):
         self.assembler.setup_once()
@@ -31,7 +34,8 @@
     def finish_once(self):
         pass
 
-    def compile_loop(self, inputargs, operations, looptoken, log=True, name=''):
+    def compile_loop(self, inputargs, operations, looptoken,
+                                                    log=True, name=''):
         self.assembler.assemble_loop(inputargs, operations,
                                                     looptoken, log=log)
 
@@ -42,15 +46,6 @@
         self.assembler.assemble_bridge(faildescr, inputargs, operations,
                                        original_loop_token, log=log)
 
-    def set_future_value_float(self, index, floatvalue):
-        self.assembler.fail_boxes_float.setitem(index, floatvalue)
-
-    def set_future_value_int(self, index, intvalue):
-        self.assembler.fail_boxes_int.setitem(index, intvalue)
-
-    def set_future_value_ref(self, index, ptrvalue):
-        self.assembler.fail_boxes_ptr.setitem(index, ptrvalue)
-
     def get_latest_value_float(self, index):
         return self.assembler.fail_boxes_float.getitem(index)
 
@@ -63,9 +58,6 @@
     def get_latest_value_count(self):
         return self.assembler.fail_boxes_count
 
-    def get_latest_value_count(self):
-        return self.assembler.fail_boxes_count
-
     def get_latest_force_token(self):
         return self.assembler.fail_force_index
 
@@ -78,27 +70,29 @@
         for index in range(count):
             setitem(index, null)
 
-    def execute_token(self, executable_token):
-        #i = [self.get_latest_value_int(x) for x in range(10)]
-        #print 'Inputargs: %r for token %r' % (i, executable_token)
-        addr = executable_token._arm_bootstrap_code
-        assert addr % 8 == 0
-        func = rffi.cast(lltype.Ptr(self.BOOTSTRAP_TP), addr)
-        fail_index = self._execute_call(func)
-        return self.get_fail_descr_from_number(fail_index)
+    def make_execute_token(self, *ARGS):
+        FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, lltype.Signed))
 
-    def _execute_call(self, func):
-        prev_interpreter = None
-        if not self.translate_support_code:
-            prev_interpreter = LLInterpreter.current_interpreter
-            LLInterpreter.current_interpreter = self.debug_ll_interpreter
-        res = 0
-        try:
-            res = func()
-        finally:
+        def execute_token(executable_token, *args):
+            clt = executable_token.compiled_loop_token
+            assert len(args) == clt._debug_nbargs
+            #
+            addr = executable_token._arm_func_addr
+            assert addr % 8 == 0
+            func = rffi.cast(FUNCPTR, addr)
+            #llop.debug_print(lltype.Void, ">>>> Entering", addr)
+            prev_interpreter = None   # help flow space
             if not self.translate_support_code:
-                LLInterpreter.current_interpreter = prev_interpreter
-        return res
+                prev_interpreter = LLInterpreter.current_interpreter
+                LLInterpreter.current_interpreter = self.debug_ll_interpreter
+            try:
+                fail_index = func(*args)
+            finally:
+                if not self.translate_support_code:
+                    LLInterpreter.current_interpreter = prev_interpreter
+            #llop.debug_print(lltype.Void, "<<<< Back")
+            return self.get_fail_descr_from_number(fail_index)
+        return execute_token
 
     def cast_ptr_to_int(x):
         adr = llmemory.cast_ptr_to_adr(x)
@@ -111,13 +105,13 @@
         fail_index = rffi.cast(TP, addr_of_force_index)[0]
         assert fail_index >= 0, "already forced!"
         faildescr = self.get_fail_descr_from_number(fail_index)
-        rffi.cast(TP, addr_of_force_index)[0] = -1
+        rffi.cast(TP, addr_of_force_index)[0] = ~fail_index
         # start of "no gc operation!" block
-        frame_depth = faildescr._arm_frame_depth*WORD
+        frame_depth = faildescr._arm_current_frame_depth * WORD
         addr_end_of_frame = (addr_of_force_index -
                             (frame_depth +
-                            len(all_regs)*WORD + 
-                            len(all_vfp_regs)*2*WORD))
+                            len(all_regs) * WORD +
+                            len(all_vfp_regs) * 2 * WORD))
         fail_index_2 = self.assembler.failure_recovery_func(
             faildescr._failure_recovery_code,
             addr_of_force_index,
diff --git a/pypy/jit/backend/arm/shift.py b/pypy/jit/backend/arm/shift.py
--- a/pypy/jit/backend/arm/shift.py
+++ b/pypy/jit/backend/arm/shift.py
@@ -3,4 +3,4 @@
 LSR = 0x1
 ASR = 0x2
 ROR = 0x3
-RRX = 0x3 # with imm = 0
+RRX = 0x3  # with imm = 0
diff --git a/pypy/jit/backend/arm/test/test_assembler.py b/pypy/jit/backend/arm/test/test_assembler.py
--- a/pypy/jit/backend/arm/test/test_assembler.py
+++ b/pypy/jit/backend/arm/test/test_assembler.py
@@ -1,8 +1,6 @@
-from pypy.jit.backend.arm import arch
 from pypy.jit.backend.arm import conditions as c
 from pypy.jit.backend.arm import registers as r
-from pypy.jit.backend.arm.arch import WORD
-from pypy.jit.backend.arm.arch import arm_int_div, arm_int_div_sign
+from pypy.jit.backend.arm.arch import arm_int_div
 from pypy.jit.backend.arm.assembler import AssemblerARM
 from pypy.jit.backend.arm.locations import imm
 from pypy.jit.backend.arm.test.support import skip_unless_arm, run_asm
@@ -10,21 +8,21 @@
 from pypy.jit.metainterp.resoperation import rop
 
 from pypy.rpython.annlowlevel import llhelper
-from pypy.rpython.lltypesystem import lltype, rffi, llmemory
-from pypy.jit.metainterp.history import LoopToken
+from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.jit.metainterp.history import JitCellToken
 from pypy.jit.backend.model import CompiledLoopToken
 
 skip_unless_arm()
 
 CPU = getcpuclass()
+
+
 class TestRunningAssembler(object):
     def setup_method(self, method):
         cpu = CPU(None, None)
-        #lp = LoopToken()
-        #lp.compiled_loop_token = CompiledLoopToken(cpu, None)
         self.a = AssemblerARM(cpu)
         self.a.setup_once()
-        token = LoopToken()
+        token = JitCellToken()
         clt = CompiledLoopToken(cpu, 0)
         clt.allgcrefs = []
         token.compiled_loop_token = clt
@@ -33,7 +31,8 @@
     def test_make_operation_list(self):
         i = rop.INT_ADD
         from pypy.jit.backend.arm import assembler
-        assert assembler.asm_operations[i] is AssemblerARM.emit_op_int_add.im_func
+        assert assembler.asm_operations[i] \
+            is AssemblerARM.emit_op_int_add.im_func
 
     def test_load_small_int_to_reg(self):
         self.a.gen_func_prolog()
@@ -77,7 +76,6 @@
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 464
 
-
     def test_or(self):
         self.a.gen_func_prolog()
         self.a.mc.MOV_ri(r.r1.value, 8)
@@ -115,7 +113,7 @@
         self.a.gen_func_prolog()
         self.a.mc.MOV_ri(r.r1.value, 1)
         loop_head = self.a.mc.currpos()
-        self.a.mc.CMP_ri(r.r1.value, 0) # z=0, z=1
+        self.a.mc.CMP_ri(r.r1.value, 0)  # z=0, z=1
         self.a.mc.MOV_ri(r.r1.value, 0, cond=c.NE)
         self.a.mc.MOV_ri(r.r1.value, 7, cond=c.EQ)
         self.a.mc.B_offs(loop_head, c.NE)
@@ -143,7 +141,8 @@
         self.a.mc.MOV_ri(r.r0.value, 123, cond=c.NE)
 
         for x in range(15):
-            self.a.mc.POP([reg.value for reg in r.callee_restored_registers], cond=c.NE)
+            self.a.mc.POP(
+                [reg.value for reg in r.callee_restored_registers], cond=c.NE)
 
         self.a.mc.MOV_ri(r.r1.value, 33)
         self.a.mc.MOV_ri(r.r0.value, 23)
@@ -160,7 +159,8 @@
         self.a.mc.MOV_ri(r.r0.value, 123, cond=c.NE)
 
         for x in range(100):
-            self.a.mc.POP([reg.value for reg in r.callee_restored_registers], cond=c.NE)
+            self.a.mc.POP(
+                [reg.value for reg in r.callee_restored_registers], cond=c.NE)
 
         self.a.mc.MOV_ri(r.r1.value, 33)
         self.a.mc.MOV_ri(r.r0.value, 23)
@@ -216,7 +216,6 @@
         self.a.gen_func_epilog()
         assert run_asm(self.a) == -36
 
-
     def test_bl_with_conditional_exec(self):
         functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
         call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
@@ -240,7 +239,7 @@
         assert run_asm(self.a) == 2478
 
     def test_load_store(self):
-        x =  0x60002224
+        x = 0x60002224
         self.a.gen_func_prolog()
         self.a.mc.gen_load_int(r.r1.value, x)
         self.a.mc.MOV_ri(r.r3.value, 8)
@@ -249,7 +248,7 @@
         self.a.gen_func_epilog()
         assert run_asm(self.a) == x
 
+
 def callme(inp):
     i = inp + 10
     return i
-
diff --git a/pypy/jit/backend/arm/test/test_calling_convention.py b/pypy/jit/backend/arm/test/test_calling_convention.py
--- a/pypy/jit/backend/arm/test/test_calling_convention.py
+++ b/pypy/jit/backend/arm/test/test_calling_convention.py
@@ -1,13 +1,15 @@
 from pypy.rpython.annlowlevel import llhelper
-from pypy.jit.metainterp.history import LoopToken
+from pypy.jit.metainterp.history import JitCellToken
 from pypy.jit.backend.test.calling_convention_test import TestCallingConv, parse
 from pypy.rpython.lltypesystem import lltype
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.backend.arm.test.support import skip_unless_arm
 skip_unless_arm()
 
-# ../../test/calling_convention_test.py
+
 class TestARMCallingConvention(TestCallingConv):
+    # ../../test/calling_convention_test.py
+
     def test_call_argument_spilling(self):
         # bug when we have a value in r0, that is overwritten by an argument
         # and needed after the call, so that the register gets spilled after it
@@ -28,11 +30,10 @@
         i99 = call(ConstClass(func_ptr), 22, descr=calldescr)
         finish(%s, i99)""" % (args, args)
         loop = parse(ops, namespace=locals())
-        looptoken = LoopToken()
+        looptoken = JitCellToken()
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
-        for x in range(11):
-            self.cpu.set_future_value_int(x, x)
-        self.cpu.execute_token(looptoken)
+        args = [x for x in range(11)]
+        self.cpu.execute_token(looptoken, *args)
         for x in range(11):
             assert self.cpu.get_latest_value_int(x) == x
         assert self.cpu.get_latest_value_int(11) == 38
diff --git a/pypy/jit/backend/arm/test/test_gc_integration.py b/pypy/jit/backend/arm/test/test_gc_integration.py
--- a/pypy/jit/backend/arm/test/test_gc_integration.py
+++ b/pypy/jit/backend/arm/test/test_gc_integration.py
@@ -3,63 +3,74 @@
 """
 
 import py
-from pypy.jit.metainterp.history import BoxInt, ConstInt,\
-     BoxPtr, ConstPtr, TreeLoop
+from pypy.jit.metainterp.history import BoxInt, \
+     BoxPtr, TreeLoop, TargetToken
 from pypy.jit.metainterp.resoperation import rop, ResOperation
 from pypy.jit.codewriter import heaptracker
 from pypy.jit.backend.llsupport.descr import GcCache
 from pypy.jit.backend.llsupport.gc import GcLLDescription
 from pypy.jit.backend.detect_cpu import getcpuclass
-from pypy.jit.backend.arm.regalloc import Regalloc
 from pypy.jit.backend.arm.arch import WORD
-from pypy.jit.tool.oparser import parse
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rpython.annlowlevel import llhelper
-from pypy.rpython.lltypesystem import rclass, rstr
-from pypy.jit.backend.llsupport.gc import GcLLDescr_framework, GcPtrFieldDescr
+from pypy.rpython.lltypesystem import rclass
+from pypy.jit.backend.llsupport.gc import GcLLDescr_framework
 
 from pypy.jit.backend.arm.test.test_regalloc import MockAssembler
 from pypy.jit.backend.arm.test.test_regalloc import BaseTestRegalloc
-from pypy.jit.backend.arm.regalloc import ARMv7RegisterMananger, ARMFrameManager,\
-     VFPRegisterManager
+from pypy.jit.backend.arm.regalloc import ARMFrameManager, VFPRegisterManager
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.backend.arm.test.support import skip_unless_arm
+from pypy.jit.backend.arm.regalloc import Regalloc, ARMv7RegisterManager
 skip_unless_arm()
 
 CPU = getcpuclass()
 
+
 class MockGcRootMap(object):
     is_shadow_stack = False
+
     def get_basic_shape(self, is_64_bit):
         return ['shape']
+
     def add_frame_offset(self, shape, offset):
         shape.append(offset)
+
     def add_callee_save_reg(self, shape, reg_index):
-        index_to_name = { 1: 'ebx', 2: 'esi', 3: 'edi' }
+        index_to_name = {1: 'ebx', 2: 'esi', 3: 'edi'}
         shape.append(index_to_name[reg_index])
+
     def compress_callshape(self, shape, datablockwrapper):
         assert datablockwrapper == 'fakedatablockwrapper'
         assert shape[0] == 'shape'
         return ['compressed'] + shape[1:]
 
+
 class MockGcRootMap2(object):
     is_shadow_stack = False
+
     def get_basic_shape(self, is_64_bit):
         return ['shape']
+
     def add_frame_offset(self, shape, offset):
         shape.append(offset)
+
     def add_callee_save_reg(self, shape, reg_index):
-        index_to_name = { 1: 'ebx', 2: 'esi', 3: 'edi' }
+        index_to_name = {1: 'ebx', 2: 'esi', 3: 'edi'}
         shape.append(index_to_name[reg_index])
+
     def compress_callshape(self, shape, datablockwrapper):
         assert datablockwrapper == 'fakedatablockwrapper'
         assert shape[0] == 'shape'
         return ['compressed'] + shape[1:]
 
+
 class MockGcDescr(GcCache):
     is_shadow_stack = False
+
     def get_funcptr_for_new(self):
         return 123
+
     get_funcptr_for_newarray = get_funcptr_for_new
     get_funcptr_for_newstr = get_funcptr_for_new
     get_funcptr_for_newunicode = get_funcptr_for_new
@@ -74,13 +85,14 @@
     record_constptrs = GcLLDescr_framework.record_constptrs.im_func
     rewrite_assembler = GcLLDescr_framework.rewrite_assembler.im_func
 
+
 class TestRegallocDirectGcIntegration(object):
 
     def test_mark_gc_roots(self):
         py.test.skip('roots')
         cpu = CPU(None, None)
         cpu.setup_once()
-        regalloc = RegAlloc(MockAssembler(cpu, MockGcDescr(False)))
+        regalloc = Regalloc(MockAssembler(cpu, MockGcDescr(False)))
         regalloc.assembler.datablockwrapper = 'fakedatablockwrapper'
         boxes = [BoxPtr() for i in range(len(ARMv7RegisterManager.all_regs))]
         longevity = {}
@@ -95,7 +107,8 @@
         for box in boxes:
             regalloc.rm.try_allocate_reg(box)
         TP = lltype.FuncType([], lltype.Signed)
-        calldescr = cpu.calldescrof(TP, TP.ARGS, TP.RESULT, EffectInfo.MOST_GENERAL)
+        calldescr = cpu.calldescrof(TP, TP.ARGS, TP.RESULT,
+                                                EffectInfo.MOST_GENERAL)
         regalloc.rm._check_invariants()
         box = boxes[0]
         regalloc.position = 0
@@ -129,6 +142,7 @@
 
     descr0 = cpu.fielddescrof(S, 'int')
     ptr0 = struct_ref
+    targettoken = TargetToken()
 
     namespace = locals().copy()
 
@@ -153,6 +167,7 @@
     def test_bug_0(self):
         ops = '''
         [i0, i1, i2, i3, i4, i5, i6, i7, i8]
+        label(i0, i1, i2, i3, i4, i5, i6, i7, i8, descr=targettoken)
         guard_value(i2, 1) [i2, i3, i4, i5, i6, i7, i0, i1, i8]
         guard_class(i4, 138998336) [i4, i5, i6, i7, i0, i1, i8]
         i11 = getfield_gc(i4, descr=descr0)
@@ -180,7 +195,7 @@
         guard_false(i32) [i4, i6, i7, i0, i1, i24]
         i33 = getfield_gc(i0, descr=descr0)
         guard_value(i33, ConstPtr(ptr0)) [i4, i6, i7, i0, i1, i33, i24]
-        jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24)
+        jump(i0, i1, 1, 17, i4, ConstPtr(ptr0), i6, i7, i24, descr=targettoken)
         '''
         self.interpret(ops, [0, 0, 0, 0, 0, 0, 0, 0, 0], run=False)
 
@@ -322,17 +337,22 @@
 class Seen(Exception):
     pass
 
+
 class GCDescrFastpathMallocVarsize(GCDescrFastpathMalloc):
     def can_inline_malloc_varsize(self, arraydescr, num_elem):
         return num_elem < 5
+
     def get_funcptr_for_newarray(self):
         return 52
+
     def init_array_descr(self, A, descr):
         descr.tid = self._counter
         self._counter += 1
+
     def args_for_new_array(self, descr):
         raise Seen("args_for_new_array")
 
+
 class TestMallocVarsizeFastpath(BaseTestRegalloc):
     def setup_method(self, method):
         cpu = CPU(None, None)
diff --git a/pypy/jit/backend/arm/test/test_generated.py b/pypy/jit/backend/arm/test/test_generated.py
--- a/pypy/jit/backend/arm/test/test_generated.py
+++ b/pypy/jit/backend/arm/test/test_generated.py
@@ -3,10 +3,10 @@
                                          AbstractDescr,
                                          BasicFailDescr,
                                          BoxInt, Box, BoxPtr,
-                                         LoopToken,
                                          ConstInt, ConstPtr,
                                          BoxObj, Const,
                                          ConstObj, BoxFloat, ConstFloat)
+from pypy.jit.metainterp.history import JitCellToken
 from pypy.jit.metainterp.resoperation import ResOperation, rop
 from pypy.rpython.test.test_llinterp import interpret
 from pypy.jit.backend.detect_cpu import getcpuclass
@@ -40,20 +40,11 @@
             ResOperation(rop.GUARD_TRUE, [v12], None, descr=faildescr1),
             ResOperation(rop.FINISH, [v9, v6, v10, v2, v8, v5, v1, v4], None, descr=faildescr2),
             ]
-        looptoken = LoopToken()
+        looptoken = JitCellToken()
         operations[2].setfailargs([v12, v8, v3, v2, v1, v11])
         cpu.compile_loop(inputargs, operations, looptoken)
-        cpu.set_future_value_int(0, -12)
-        cpu.set_future_value_int(1, -26)
-        cpu.set_future_value_int(2, -19)
-        cpu.set_future_value_int(3, 7)
-        cpu.set_future_value_int(4, -5)
-        cpu.set_future_value_int(5, -24)
-        cpu.set_future_value_int(6, -37)
-        cpu.set_future_value_int(7, 62)
-        cpu.set_future_value_int(8, 9)
-        cpu.set_future_value_int(9, 12)
-        op = cpu.execute_token(looptoken)
+        args = [-12 , -26 , -19 , 7 , -5 , -24 , -37 , 62 , 9 , 12]
+        op = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_value_int(0) == 0
         assert cpu.get_latest_value_int(1) == 62
         assert cpu.get_latest_value_int(2) == -19
@@ -101,19 +92,10 @@
             ]
         operations[2].setfailargs([v10, v6])
         operations[9].setfailargs([v15, v7, v10, v18, v4, v17, v1])
-        looptoken = LoopToken()
+        looptoken = JitCellToken()
         cpu.compile_loop(inputargs, operations, looptoken)
-        cpu.set_future_value_int(0, 16)
-        cpu.set_future_value_int(1, 5)
-        cpu.set_future_value_int(2, 5)
-        cpu.set_future_value_int(3, 16)
-        cpu.set_future_value_int(4, 46)
-        cpu.set_future_value_int(5, 6)
-        cpu.set_future_value_int(6, 63)
-        cpu.set_future_value_int(7, 39)
-        cpu.set_future_value_int(8, 78)
-        cpu.set_future_value_int(9, 0)
-        op = cpu.execute_token(looptoken)
+        args = [16 , 5 , 5 , 16 , 46 , 6 , 63 , 39 , 78 , 0]
+        op = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_value_int(0) == 105
         assert cpu.get_latest_value_int(1) == 63
         assert cpu.get_latest_value_int(2) == 0
@@ -152,18 +134,9 @@
             ]
         operations[2].setfailargs([v8, v3])
         operations[4].setfailargs([v2, v12, v1, v3, v4])
-        looptoken = LoopToken()
+        looptoken = JitCellToken()
         cpu.compile_loop(inputargs, operations, looptoken)
-        cpu.set_future_value_int(0, -5)
-        cpu.set_future_value_int(1, 24)
-        cpu.set_future_value_int(2, 46)
-        cpu.set_future_value_int(3, -15)
-        cpu.set_future_value_int(4, 13)
-        cpu.set_future_value_int(5, -8)
-        cpu.set_future_value_int(6, 0)
-        cpu.set_future_value_int(7, -6)
-        cpu.set_future_value_int(8, 6)
-        cpu.set_future_value_int(9, 6)
+        args = [-5 , 24 , 46 , -15 , 13 , -8 , 0 , -6 , 6 , 6]
         op = cpu.execute_token(looptoken)
         assert op.identifier == 2
         assert cpu.get_latest_value_int(0) == 24
@@ -203,19 +176,10 @@
             ResOperation(rop.FINISH, [v8, v2, v6, v5, v7, v1, v10], None, descr=faildescr2),
             ]
         operations[5].setfailargs([])
-        looptoken = LoopToken()
+        looptoken = JitCellToken()
         cpu.compile_loop(inputargs, operations, looptoken)
-        cpu.set_future_value_int(0, 19)
-        cpu.set_future_value_int(1, -3)
-        cpu.set_future_value_int(2, -58)
-        cpu.set_future_value_int(3, -7)
-        cpu.set_future_value_int(4, 12)
-        cpu.set_future_value_int(5, 22)
-        cpu.set_future_value_int(6, -54)
-        cpu.set_future_value_int(7, -29)
-        cpu.set_future_value_int(8, -19)
-        cpu.set_future_value_int(9, -64)
-        op = cpu.execute_token(looptoken)
+        args = [19 , -3 , -58 , -7 , 12 , 22 , -54 , -29 , -19 , -64]
+        op = cpu.execute_token(looptoken, *args)
         assert cpu.get_latest_value_int(0) == -29
         assert cpu.get_latest_value_int(1) == -3
         assert cpu.get_latest_value_int(2) == 22
@@ -254,20 +218,11 @@
             ResOperation(rop.GUARD_NO_OVERFLOW, [], None, descr=faildescr1),
             ResOperation(rop.FINISH, [v1, v4, v10, v8, v7, v3], None, descr=faildescr2),
             ]
-        looptoken = LoopToken()
+        looptoken = JitCellToken()
         operations[5].setfailargs([])
         cpu.compile_loop(inputargs, operations, looptoken)
-        cpu.set_future_value_int(0, 1073741824)
-        cpu.set_future_value_int(1, 95)
-        cpu.set_future_value_int(2, -16)
-        cpu.set_future_value_int(3, 5)
-        cpu.set_future_value_int(4, 92)
-        cpu.set_future_value_int(5, 12)
-        cpu.set_future_value_int(6, 32)
-        cpu.set_future_value_int(7, 17)
-        cpu.set_future_value_int(8, 37)


More information about the pypy-commit mailing list