Commits

mattip committed 421ad50 Merge

merge default into about-to-be-reviewed branch

  • Participants
  • Parent commits 3744249, ce89f6b
  • Branches missing-ndarray-attributes

Comments (0)

Files changed (61)

lib-python/2.7/test/test_iterlen.py

 
     def test_no_len_for_infinite_repeat(self):
         # The repeat() object can also be infinite
-        self.assertRaises(TypeError, len, repeat(None))
+        if test_support.check_impl_detail(pypy=True):
+            # 3.4 (PEP 424) behavior
+            self.assertEqual(len(repeat(None)), NotImplemented)
+        else:
+            self.assertRaises(TypeError, len, repeat(None))
 
 class TestXrange(TestInvariantWithoutMutations):
 
         self.assertRaises(RuntimeError, b.extend, BadLen())
         self.assertRaises(RuntimeError, b.extend, BadLengthHint())
 
+    @test_support.impl_detail("PEP 424 disallows None results", pypy=False)
     def test_invalid_hint(self):
         # Make sure an invalid result doesn't muck-up the works
         self.assertEqual(list(NoneLengthHint()), list(range(10)))

lib-python/conftest.py

     RegrTest('test_ioctl.py'),
     RegrTest('test_isinstance.py', core=True),
     RegrTest('test_iter.py', core=True),
-    RegrTest('test_iterlen.py', skip="undocumented internal API behavior __length_hint__"),
+    RegrTest('test_iterlen.py', core=True, usemodules="_collections itertools"),
     RegrTest('test_itertools.py', core=True, usemodules="itertools struct"),
     RegrTest('test_json.py'),
     RegrTest('test_kqueue.py'),

py/_code/source.py

                 trysource = self[start:end]
                 if trysource.isparseable():
                     return start, end
+                if end == start + 100:   # XXX otherwise, it takes forever
+                    break                # XXX
         if end is None:
             raise IndexError("no valid source range around line %d " % (lineno,))
         return start, end

pypy/doc/getting-started-python.rst

 
 4. Run::
 
-     cd pypy/translator/goal
-     python translate.py --opt=jit targetpypystandalone.py
+     cd pypy/goal
+     python ../../rpython/bin/rpython --opt=jit targetpypystandalone.py
 
    possibly replacing ``--opt=jit`` with another `optimization level`_
    of your choice like ``--opt=2`` if you do not want to include the JIT

pypy/doc/whatsnew-head.rst

 .. branch: kill-faking
 .. branch: improved_ebnfparse_error
 .. branch: task-decorator
+.. branch: fix-e4fa0b2
+.. branch: win32-fixes
 
 .. branch: release-2.0-beta1
 
 
 .. branch: fix-lookinside-iff-oopspec
 Fixed the interaction between two internal tools for controlling the JIT.
+
+.. branch: inline-virtualref-2
+Better optimized certain types of frame accesses in the JIT, particularly
+around exceptions that escape the function they were raised in.

pypy/interpreter/app_main.py

     def pypy_find_stdlib(s):
         from os.path import abspath, join, dirname as dn
         thisfile = abspath(__file__)
-        root = dn(dn(dn(dn(thisfile))))
+        root = dn(dn(dn(thisfile)))
         return [join(root, 'lib-python', '2.7'),
                 join(root, 'lib_pypy')]
     
     def pypy_resolvedirof(s):
         # we ignore the issue of symlinks; for tests, the executable is always
-        # translator/goal/app_main.py anyway
+        # interpreter/app_main.py anyway
         import os
         return os.path.abspath(os.path.join(s, '..'))
 

pypy/interpreter/test2/test_app_main.py

             assert line.rstrip() == 'Not at all. They could be carried.'
             print 'A five ounce bird could not carry a one pound coconut.'
             """)
-        py_py = os.path.join(pypydir, 'bin', 'py.py')
+        py_py = os.path.join(pypydir, 'bin', 'pyinteractive.py')
         child = self._spawn(sys.executable, [py_py, '-S', path])
         child.expect('Are you suggesting coconuts migrate?', timeout=120)
         child.sendline('Not at all. They could be carried.')
         sys.path.append(self.goal_dir)
         try:
             import app_main
-            pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c')
+            pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c')
             app_main.setup_bootstrap_path(pypy_c)
             newpath = sys.path[:]
             # we get at least lib_pypy 
         sys.path.append(self.goal_dir)
         try:
             import app_main
-            pypy_c = os.path.join(self.trunkdir, 'pypy', 'translator', 'goal', 'pypy-c')
+            pypy_c = os.path.join(self.trunkdir, 'pypy', 'goal', 'pypy-c')
             app_main.entry_point(pypy_c, [self.foo_py])
             # assert it did not crash
         finally:

pypy/module/_collections/interp_deque.py

         return self.space.wrap(self.counter)
 
     def next(self):
-        self.deque.checklock(self.lock)
+        if self.lock is not self.deque.lock:
+            self.counter = 0
+            raise OperationError(
+                self.space.w_RuntimeError,
+                self.space.wrap("deque mutated during iteration"))
         if self.counter == 0:
             raise OperationError(self.space.w_StopIteration, self.space.w_None)
         self.counter -= 1
         return self.space.wrap(self.counter)
 
     def next(self):
-        self.deque.checklock(self.lock)
+        if self.lock is not self.deque.lock:
+            self.counter = 0
+            raise OperationError(
+                self.space.w_RuntimeError,
+                self.space.wrap("deque mutated during iteration"))
         if self.counter == 0:
             raise OperationError(self.space.w_StopIteration, self.space.w_None)
         self.counter -= 1

pypy/module/pypyjit/test_pypy_c/test_thread.py

             --THREAD-TICK--
             jump(..., descr=...)
         """)
+
+    def test_tls(self):
+        def main(n):
+            import thread
+            local = thread._local()
+            local.x = 1
+            i = 0
+            while i < n:
+                i += local.x
+            return 0
+        log = self.run(main, [500])
+        assert round(log.result, 6) == round(main(500), 6)
+        loop, = log.loops_by_filename(self.filepath)
+        assert loop.match("""
+            i53 = int_lt(i48, i27)
+            guard_true(i53, descr=...)
+            i54 = int_add_ovf(i48, i47)
+            guard_no_overflow(descr=...)
+            --TICK--
+            i58 = arraylen_gc(p43, descr=...)
+            jump(p0, p1, p3, p5, p10, p12, p14, i54, i27, i47, p45, p43, descr=...)
+        """)

pypy/module/rctime/interp_time.py

             raise OperationError(space.w_ValueError,
                 space.wrap("year out of range"))
 
+    # tm_wday does not need checking of its upper-bound since taking "%
+    #  7" in gettmarg() automatically restricts the range.
+    if rffi.getintfield(glob_buf, 'c_tm_wday') < -1:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("day of week out of range"))
+
     rffi.setintfield(glob_buf, 'c_tm_year', y - 1900)
     rffi.setintfield(glob_buf, 'c_tm_mon',
                      rffi.getintfield(glob_buf, 'c_tm_mon') - 1)
     rffi.setintfield(glob_buf, 'c_tm_yday',
                      rffi.getintfield(glob_buf, 'c_tm_yday') - 1)
 
-    # tm_wday does not need checking of its upper-bound since taking "%
-    #  7" in gettmarg() automatically restricts the range.
-    if rffi.getintfield(glob_buf, 'c_tm_wday') < 0:
-        raise OperationError(space.w_ValueError,
-                             space.wrap("day of week out of range"))
-
     return glob_buf
 
 def time(space):

pypy/module/signal/test/test_signal.py

 
 class AppTestSignal:
     spaceconfig = {
-        "usemodules": ['signal', 'rctime'],
+        "usemodules": ['signal', 'rctime'] + (['fcntl'] if os.name != 'nt' else []),
     }
 
     def setup_class(cls):

pypy/module/sys/version.py

 import pypy
 pypydir = os.path.dirname(os.path.abspath(pypy.__file__))
 del pypy
-from pypy.tool.version import get_repo_version_info
+from rpython.tool.version import get_repo_version_info
 
 import time as t
 gmtime = t.gmtime()

pypy/module/sys/vm.py

 def exc_info_with_tb(space):
     operror = space.getexecutioncontext().sys_exc_info()
     if operror is None:
-        return space.newtuple([space.w_None,space.w_None,space.w_None])
+        return space.newtuple([space.w_None, space.w_None, space.w_None])
     else:
         return space.newtuple([operror.w_type, operror.get_w_value(space),
                                space.wrap(operror.get_traceback())])

pypy/module/thread/os_local.py

         w_dict = space.newdict(instance=True)
         self.dicts[ec] = w_dict
         self._register_in_ec(ec)
+        # cache the last seen dict, works because we are protected by the GIL
+        self.last_dict = w_dict
+        self.last_ec = ec
 
     def _register_in_ec(self, ec):
         if not ec.space.config.translation.rweakref:
 
     def getdict(self, space):
         ec = space.getexecutioncontext()
+        if ec is self.last_ec:
+            return self.last_dict
         try:
             w_dict = self.dicts[ec]
         except KeyError:
             w_dict = self.create_new_dict(ec)
+        self.last_ec = ec
+        self.last_dict = w_dict
         return w_dict
 
     def descr_local__new__(space, w_subtype, __args__):
         local = wref()
         if local is not None:
             del local.dicts[ec]
+        local.last_dict = None
+        local.last_ec = None

pypy/module/thread/test/test_local.py

         gc.collect()
         assert done == ['ok', 'del']
         done.append('shutdown')
+
+def test_local_caching():
+    from pypy.module.thread.os_local import Local
+    class FakeSpace:
+        def getexecutioncontext(self):
+            return self.ec
+
+        def getattr(*args):
+            pass
+        def call_obj_args(*args):
+            pass
+        def newdict(*args, **kwargs):
+            return {}
+        def wrap(self, obj):
+            return obj
+        def type(self, obj):
+            return type(obj)
+        class config:
+            class translation:
+                rweakref = True
+
+    class FakeEC:
+        def __init__(self, space):
+            self.space = space
+            self._thread_local_objs = None
+    space = FakeSpace()
+    ec1 = FakeEC(space)
+    space.ec = ec1
+
+    l = Local(space, None)
+    assert l.last_dict is l.dicts[ec1]
+    assert l.last_ec is ec1
+    d1 = l.getdict(space)
+    assert d1 is l.last_dict
+
+    ec2 = space.ec = FakeEC(space)
+    d2 = l.getdict(space)
+    assert l.last_dict is d2
+    assert d2 is l.dicts[ec2]
+    assert l.last_ec is ec2
+    dicts = l.dicts
+    l.dicts = "nope"
+    assert l.getdict(space) is d2
+    l.dicts = dicts
+
+    space.ec = ec1
+    assert l.getdict(space) is d1
+    l.dicts = "nope"
+    assert l.getdict(space) is d1
+    l.dicts = dicts
+

pypy/module/thread/test/test_thread.py

         import signal
 
         def f():
-            time.sleep(0.5)
-            thread.interrupt_main()
+            for x in range(50):
+                if waiting:
+                    thread.interrupt_main()
+                    return
+                print 'tock...', x  # <-force the GIL to be released, as
+                time.sleep(0.01)    #   time.sleep doesn't do non-translated
 
         def busy_wait():
-            for x in range(1000):
+            waiting.append(None)
+            for x in range(100):
                 print 'tick...', x  # <-force the GIL to be released, as
                 time.sleep(0.01)    #   time.sleep doesn't do non-translated
+            waiting.pop()
 
         # This is normally called by app_main.py
         signal.signal(signal.SIGINT, signal.default_int_handler)
 
-        thread.start_new_thread(f, ())
-        raises(KeyboardInterrupt, busy_wait)
+        for i in range(100):
+            waiting = []
+            thread.start_new_thread(f, ())
+            raises(KeyboardInterrupt, busy_wait)

pypy/module/unicodedata/interp_ucd.py

 from rpython.rlib.objectmodel import we_are_translated
 from rpython.rlib.runicode import MAXUNICODE
 from rpython.rlib.unicodedata import unicodedb_5_2_0, unicodedb_3_2_0
-from rpython.rlib.runicode import code_to_unichr, ORD
+from rpython.rlib.runicode import code_to_unichr, ord_accepts_surrogate
 import sys
 
 
 # handling: on narrow unicode builds, a surrogate pair is considered as one
 # unicode code point.
 
-# The functions below are subtly different from the ones in runicode.py.
-# When PyPy implements Python 3 they should be merged.
 
 if MAXUNICODE > 0xFFFF:
     # Target is wide build
         if not we_are_translated() and sys.maxunicode == 0xFFFF:
             # Host CPython is narrow build, accept surrogates
             try:
-                return ORD(space.unicode_w(w_unichr))
+                return ord_accepts_surrogate(space.unicode_w(w_unichr))
             except ValueError:
                 raise OperationError(space.w_TypeError, space.wrap(
                     'need a single Unicode character as parameter'))
         else:
             # Accept surrogates
             try:
-                return ORD(space.unicode_w(w_unichr))
+                return ord_accepts_surrogate(space.unicode_w(w_unichr))
             except ValueError:
                 raise OperationError(space.w_TypeError, space.wrap(
                     'need a single Unicode character as parameter'))

pypy/module/unicodedata/test/test_unicodedata.py

         import unicodedata
         raises(TypeError, unicodedata.normalize, 'x')
 
-    @py.test.mark.skipif("sys.maxunicode < 0x10ffff",
-                         reason="requires a 'wide' python build.")
+    @py.test.mark.skipif("sys.maxunicode < 0x10ffff")
     def test_normalize_wide(self):
         import unicodedata
         assert unicodedata.normalize('NFC', u'\U000110a5\U000110ba') == u'\U000110ab'

pypy/objspace/std/bytearraytype.py

     str_splitlines, str_translate)
 from pypy.objspace.std.listtype import (
     list_append, list_extend)
+from rpython.rlib.objectmodel import newlist_hint, resizelist_hint
 
 
 bytearray_insert  = SMM('insert', 3,
         return [c for c in string]
 
     # sequence of bytes
-    data = []
     w_iter = space.iter(w_source)
+    length_hint = space.length_hint(w_source, 0)
+    data = newlist_hint(length_hint)
+    extended = 0
     while True:
         try:
             w_item = space.next(w_iter)
             break
         value = getbytevalue(space, w_item)
         data.append(value)
+        extended += 1
+    if extended < length_hint:
+        resizelist_hint(data, extended)
     return data
 
 def descr_bytearray__reduce__(space, w_self):

pypy/objspace/std/dictmultiobject.py

             # every module needs its own strategy, because the strategy stores
             # the version tag
             strategy = ModuleDictStrategy(space)
+        elif space.config.objspace.std.withmapdict and instance:
+            from pypy.objspace.std.mapdict import MapDictStrategy
+            strategy = space.fromcache(MapDictStrategy)
 
         elif instance or strdict or module:
             assert w_type is None
         self.pos = 0
 
     def length(self):
-        if self.dictimplementation is not None:
+        if self.dictimplementation is not None and self.len != -1:
             return self.len - self.pos
         return 0
 

pypy/objspace/std/mapdict.py

 # ____________________________________________________________
 # dict implementation
 
+def get_terminator_for_dicts(space):
+    return DictTerminator(space, None)
+
 class MapDictStrategy(DictStrategy):
 
     erase, unerase = rerased.new_erasing_pair("map")
     def __init__(self, space):
         self.space = space
 
+    def get_empty_storage(self):
+        w_result = Object()
+        terminator = self.space.fromcache(get_terminator_for_dicts)
+        w_result._init_empty(terminator)
+        return self.erase(w_result)
+
     def switch_to_object_strategy(self, w_dict):
         w_obj = self.unerase(w_dict.dstorage)
         strategy = self.space.fromcache(ObjectDictStrategy)
         dict_w = strategy.unerase(strategy.get_empty_storage())
         w_dict.strategy = strategy
         w_dict.dstorage = strategy.erase(dict_w)
-        assert w_obj.getdict(self.space) is w_dict
+        assert w_obj.getdict(self.space) is w_dict or w_obj._get_mapdict_map().terminator.w_cls is None
         materialize_r_dict(self.space, w_obj, dict_w)
 
     def getitem(self, w_dict, w_key):

pypy/objspace/std/setobject.py

         raise NotImplementedError
 
     def length(self):
-        if self.setimplementation is not None:
+        if self.setimplementation is not None and self.len != -1:
             return self.len - self.pos
         return 0
 

pypy/objspace/std/test/test_dictmultiobject.py

             withcelldict = False
             withmethodcache = False
             withidentitydict = False
+            withmapdict = False
 
 FakeSpace.config = Config()
 

pypy/objspace/std/test/test_lengthhint.py

     SIZE = 4
     ITEMS = range(SIZE)
 
-    def _test_length_hint(self, w_obj):
+    def _test_length_hint(self, w_obj, w_mutate=None):
         space = self.space
         assert space.length_hint(w_obj, 8) == self.SIZE
 
         space.next(w_iter)
         assert space.length_hint(w_iter, 8) == self.SIZE - 1
 
+        if w_mutate is not None:
+            # Test handling of collections that enforce length
+            # immutability during iteration
+            space.call_function(w_mutate)
+            space.raises_w(space.w_RuntimeError, space.next, w_iter)
+            assert space.length_hint(w_iter, 8) == 0
+
     def test_bytearray(self):
         space = self.space
         w_bytearray = space.call_function(space.w_bytearray,
         self._test_length_hint(w_dict)
 
     def test_dict_iterkeys(self):
-        w_iterkeys = self.space.appexec([], """():
-            return dict.fromkeys(%r).iterkeys()
-        """ % self.ITEMS)
-        self._test_length_hint(w_iterkeys)
+        space = self.space
+        w_iterkeys, w_mutate = space.fixedview(space.appexec([], """():
+            d = dict.fromkeys(%r)
+            return d.iterkeys(), d.popitem
+        """ % self.ITEMS), 2)
+        self._test_length_hint(w_iterkeys, w_mutate)
 
     def test_dict_values(self):
-        w_itervalues = self.space.appexec([], """():
-            return dict.fromkeys(%r).itervalues()
-        """ % self.ITEMS)
-        self._test_length_hint(w_itervalues)
+        space = self.space
+        w_itervalues, w_mutate = space.fixedview(space.appexec([], """():
+            d = dict.fromkeys(%r)
+            return d.itervalues(), d.popitem
+        """ % self.ITEMS), 2)
+        self._test_length_hint(w_itervalues, w_mutate)
 
     def test_frozenset(self):
         space = self.space
     def test_set(self):
         space = self.space
         w_set = space.call_function(space.w_set, space.wrap(self.ITEMS))
-        self._test_length_hint(w_set)
+        w_mutate = space.getattr(w_set, space.wrap('pop'))
+        self._test_length_hint(w_set, w_mutate)
 
     def test_list(self):
         self._test_length_hint(self.space.wrap(self.ITEMS))
         self._test_length_hint(W_Repeat(space, space.wrap(22),
                                         space.wrap(self.SIZE)))
 
-    def test_collections_deque(self):
+    def _setup_deque(self):
         space = self.space
         w_deque = W_Deque(space)
         space.call_method(w_deque, '__init__', space.wrap(self.ITEMS))
-        self._test_length_hint(w_deque)
-        self._test_length_hint(w_deque.reviter())
+        w_mutate = space.getattr(w_deque, space.wrap('pop'))
+        return w_deque, w_mutate
+
+    def test_collections_deque(self):
+        self._test_length_hint(*self._setup_deque())
+
+    def test_collections_deque_rev(self):
+        w_deque, w_mutate = self._setup_deque()
+        self._test_length_hint(w_deque.reviter(), w_mutate)
 
     def test_default(self):
         space = self.space

pypy/objspace/std/test/test_mapdict.py

 from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictMultiObject
 from pypy.objspace.std.mapdict import *
 
+class Config:
+    class objspace:
+        class std:
+            withsmalldicts = False
+            withcelldict = False
+            withmethodcache = False
+            withidentitydict = False
+            withmapdict = True
+
 space = FakeSpace()
+space.config = Config
 
 class Class(object):
     def __init__(self, hasdict=True):
                 return A()
                 """)
         assert w_dict.user_overridden_class
+
+def test_newdict_instance():
+    w_dict = space.newdict(instance=True)
+    assert type(w_dict.strategy) is MapDictStrategy
+
+class TestMapDictImplementationUsingnewdict(BaseTestRDictImplementation):
+    StrategyClass = MapDictStrategy
+    # NB: the get_impl method is not overwritten here, as opposed to above

pypy/tool/jitlogparser/parser.py

     _lineset = None
     is_bytecode = False
     inline_level = None
+    bytecode_name = None
 
     # factory method
     TraceForOpcode = TraceForOpcode
             return ",".join([str(len(v)) for v in stack])
 
         def append_to_res(bc):
-            if not stack:
-                stack.append([])
-            else:
-                if bc.inline_level is not None and bc.inline_level + 1 != len(stack):
-                    if bc.inline_level < len(stack):
+            if bc.inline_level is not None:
+                if bc.inline_level == len(stack) - 1:
+                    pass
+                elif bc.inline_level > len(stack) - 1:
+                    stack.append([])
+                else:
+                    while bc.inline_level + 1 < len(stack):
                         last = stack.pop()
                         stack[-1].append(cls(last, getpath(stack), storage))
-                    else:
-                        stack.append([])
             stack[-1].append(bc)
 
         so_far = []
         stack = []
+        nothing_yet = True
         for op in operations:
             if op.name == 'debug_merge_point':
                 if so_far:
-                    append_to_res(cls.TraceForOpcode(so_far, storage, loopname))
+                    opc = cls.TraceForOpcode(so_far, storage, loopname)
+                    if nothing_yet:
+                        nothing_yet = False
+                        for i in xrange(opc.inline_level + 1):
+                            stack.append([])
+                    append_to_res(opc)
                     if limit:
                         break
                     so_far = []

pypy/tool/jitlogparser/test/test_parser.py

     f = Function.from_operations(loop.operations, LoopStorage())
     assert f.chunks[-1].filename == 'x.py'
     assert f.filename is None
+
+def test_parse_2_levels_up():
+    loop = parse("""
+    []
+    debug_merge_point(0, 0, 'one')
+    debug_merge_point(1, 0, 'two')
+    debug_merge_point(2, 0, 'three')
+    debug_merge_point(0, 0, 'one')    
+    """)
+    f = Function.from_operations(loop.operations, LoopStorage())
+    assert len(f.chunks) == 3
+
+def test_parse_from_inside():
+    loop = parse("""
+    []
+    debug_merge_point(1, 0, 'two')
+    debug_merge_point(2, 0, 'three')
+    debug_merge_point(0, 0, 'one')    
+    """)
+    f = Function.from_operations(loop.operations, LoopStorage())
+    assert len(f.chunks) == 2
+    

pypy/tool/release/package.py

 #!/usr/bin/env python
 """ A sample script that packages PyPy, provided that it's already built.
-It uses 'pypy/translator/goal/pypy-c' and parts of the rest of the working
+It uses 'pypy/goal/pypy-c' and parts of the rest of the working
 copy.  Usage:
 
     package.py root-pypy-dir [name-of-archive] [name-of-pypy-c] [destination-for-tarball] [pypy-c-path]
 import sys
 import os
 #Add toplevel repository dir to sys.path
-sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))))
+sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))))
 import py
 import fnmatch
 from rpython.tool.udir import udir

pypy/tool/release/test/test_package.py

         basename = 'pypy-c'
         rename_pypy_c = 'pypy'
         exe_name_in_archive = 'bin/pypy'
-    pypy_c = py.path.local(pypydir).join('..', basename)
+    pypy_c = py.path.local(pypydir).join('goal', basename)
     if not pypy_c.check():
         os.system("echo faked_pypy_c> %s" % (pypy_c,))
         pypy_c.chmod(0755)

pypy/tool/rundictbenchmarks.py

 # this file runs some benchmarks with a pypy-c that is assumed to be
 # built using the MeasuringDictImplementation.
 
-# it should be run with pypy/translator/goal as the cwd, and you'll
+# it should be run with pypy/goal as the cwd, and you'll
 # need to hack a copy of rst2html for yourself (svn docutils
 # required).
 

pypy/tool/test/test_version.py

-import os, sys
-import py
-from pypy.tool.version import get_repo_version_info, _get_hg_archive_version
-
-def test_hg_archival_version(tmpdir):
-    def version_for(name, **kw):
-        path = tmpdir.join(name)
-        path.write('\n'.join('%s: %s' % x for x in kw.items()))
-        return _get_hg_archive_version(str(path))
-
-    assert version_for('release',
-                       tag='release-123',
-                       node='000',
-                      ) == ('PyPy', 'release-123', '000')
-    assert version_for('somebranch',
-                       node='000',
-                       branch='something',
-                      ) == ('PyPy', 'something', '000')
-
-
-def test_get_repo_version_info():
-    assert get_repo_version_info(None)
-    assert get_repo_version_info(os.devnull) == ('PyPy', '?', '?')
-    assert get_repo_version_info(sys.executable) == ('PyPy', '?', '?')

pypy/tool/version.py

-import py
-import os
-from subprocess import Popen, PIPE
-import pypy
-pypydir = os.path.dirname(os.path.abspath(pypy.__file__))
-pypyroot = os.path.dirname(pypydir)
-default_retval = 'PyPy', '?', '?'
-
-def maywarn(err, repo_type='Mercurial'):
-    if not err:
-        return
-
-    from rpython.tool.ansi_print import ansi_log
-    log = py.log.Producer("version")
-    py.log.setconsumer("version", ansi_log)
-    log.WARNING('Errors getting %s information: %s' % (repo_type, err))
-
-def get_repo_version_info(hgexe=None):
-    '''Obtain version information by invoking the 'hg' or 'git' commands.'''
-
-    # Try to see if we can get info from Git if hgexe is not specified.
-    if not hgexe:
-        if os.path.isdir(os.path.join(pypyroot, '.git')):
-            return _get_git_version()
-
-    # Fallback to trying Mercurial.
-    if hgexe is None:
-        hgexe = py.path.local.sysfind('hg')
-
-    if os.path.isfile(os.path.join(pypyroot, '.hg_archival.txt')):
-        return _get_hg_archive_version(os.path.join(pypyroot, '.hg_archival.txt'))
-    elif not os.path.isdir(os.path.join(pypyroot, '.hg')):
-        maywarn('Not running from a Mercurial repository!')
-        return default_retval
-    elif not hgexe:
-        maywarn('Cannot find Mercurial command!')
-        return default_retval
-    else:
-        return _get_hg_version(hgexe)
-
-
-def _get_hg_version(hgexe):
-    env = dict(os.environ)
-    # get Mercurial into scripting mode
-    env['HGPLAIN'] = '1'
-    # disable user configuration, extensions, etc.
-    env['HGRCPATH'] = os.devnull
-
-    try:
-        p = Popen([str(hgexe), 'version', '-q'],
-                  stdout=PIPE, stderr=PIPE, env=env)
-    except OSError, e:
-        maywarn(e)
-        return default_retval
-
-    if not p.stdout.read().startswith('Mercurial Distributed SCM'):
-        maywarn('command does not identify itself as Mercurial')
-        return default_retval
-
-    p = Popen([str(hgexe), 'id', '-i', pypyroot],
-              stdout=PIPE, stderr=PIPE, env=env)
-    hgid = p.stdout.read().strip()
-    maywarn(p.stderr.read())
-    if p.wait() != 0:
-        hgid = '?'
-
-    p = Popen([str(hgexe), 'id', '-t', pypyroot],
-              stdout=PIPE, stderr=PIPE, env=env)
-    hgtags = [t for t in p.stdout.read().strip().split() if t != 'tip']
-    maywarn(p.stderr.read())
-    if p.wait() != 0:
-        hgtags = ['?']
-
-    if hgtags:
-        return 'PyPy', hgtags[0], hgid
-    else:
-        # use the branch instead
-        p = Popen([str(hgexe), 'id', '-b', pypyroot],
-                  stdout=PIPE, stderr=PIPE, env=env)
-        hgbranch = p.stdout.read().strip()
-        maywarn(p.stderr.read())
-
-        return 'PyPy', hgbranch, hgid
-
-
-def _get_hg_archive_version(path):
-    fp = open(path)
-    try:
-        data = dict(x.split(': ', 1) for x in fp.read().splitlines())
-    finally:
-        fp.close()
-    if 'tag' in data:
-        return 'PyPy', data['tag'], data['node']
-    else:
-        return 'PyPy', data['branch'], data['node']
-
-
-def _get_git_version():
-    #XXX: this function is a untested hack,
-    #     so the git mirror tav made will work
-    gitexe = py.path.local.sysfind('git')
-    if not gitexe:
-        return default_retval
-
-    try:
-        p = Popen(
-            [str(gitexe), 'rev-parse', 'HEAD'],
-            stdout=PIPE, stderr=PIPE, cwd=pypyroot
-            )
-    except OSError, e:
-        maywarn(e, 'Git')
-        return default_retval
-    if p.wait() != 0:
-        maywarn(p.stderr.read(), 'Git')
-        return default_retval
-    revision_id = p.stdout.read().strip()[:12]
-    p = Popen(
-        [str(gitexe), 'describe', '--tags', '--exact-match'],
-        stdout=PIPE, stderr=PIPE, cwd=pypyroot
-        )
-    if p.wait() != 0:
-        p = Popen(
-            [str(gitexe), 'branch'], stdout=PIPE, stderr=PIPE,
-            cwd=pypyroot
-            )
-        if p.wait() != 0:
-            maywarn(p.stderr.read(), 'Git')
-            return 'PyPy', '?', revision_id
-        branch = '?'
-        for line in p.stdout.read().strip().split('\n'):
-            if line.startswith('* '):
-                branch = line[1:].strip()
-                if branch == '(no branch)':
-                    branch = '?'
-                break
-        return 'PyPy', branch, revision_id
-    return 'PyPy', p.stdout.read().strip(), revision_id
-
-
-if __name__ == '__main__':
-    print get_repo_version_info()

rpython/annotator/builtin.py

         s_item = s_ImpossibleValue
     else:
         nonneg = False # so far
-        if step > 0:
+        if step > 0 or s_step.nonneg:
             nonneg = s_start.nonneg
         elif step < 0:
             nonneg = s_stop.nonneg or (s_stop.is_constant() and

rpython/annotator/test/test_annrpython.py

         assert isinstance(s, annmodel.SomeInteger)
         assert s.nonneg
 
+    def test_range_nonneg_variablestep(self):
+        def get_step(n):
+            if n == 1:
+                return 2
+            else:
+                return 3
+        def fun(n, k):
+            step = get_step(n)
+            for i in range(0, n, step):
+                if k == 17:
+                    return i
+            return 0
+        a = self.RPythonAnnotator()
+        s = a.build_types(fun, [int, int])
+        assert isinstance(s, annmodel.SomeInteger)
+        assert s.nonneg
+
     def test_reverse_range_nonneg(self):
         def fun(n, k):
             for i in range(n-1, -1, -1):
         a = self.RPythonAnnotator()
         s = a.build_types(f, [str])
         assert isinstance(s, annmodel.SomeString)
+        assert s.no_nul
 
         def f(x):
             return u'a'.replace(x, u'b')

rpython/annotator/unaryop.py

         return getbookkeeper().newlist(s_item)
 
     def method_replace(str, s1, s2):
-        return str.basestringclass()
+        return str.basestringclass(no_nul=str.no_nul and s2.no_nul)
 
     def getslice(str, s_start, s_stop):
         check_negative_slice(s_start, s_stop)

rpython/jit/backend/llgraph/llimpl.py

-"""
-The non-RPythonic part of the llgraph backend.
-This contains all the code that is directly run
-when executing on top of the llinterpreter.
-"""
-
-import weakref
-from rpython.flowspace.model import Variable, Constant
-from rpython.annotator import model as annmodel
-from rpython.jit.metainterp.history import REF, INT, FLOAT
-from rpython.jit.metainterp import history
-from rpython.jit.codewriter import heaptracker
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rstr, rffi
-from rpython.rtyper.ootypesystem import ootype
-from rpython.rtyper.module.support import LLSupport, OOSupport
-from rpython.rtyper.llinterp import LLException
-from rpython.rtyper.extregistry import ExtRegistryEntry
-
-from rpython.jit.metainterp import resoperation
-from rpython.jit.metainterp.resoperation import rop
-from rpython.jit.backend.llgraph import symbolic
-from rpython.jit.codewriter import longlong
-from rpython.jit.codewriter.effectinfo import EffectInfo
-
-from rpython.rlib.objectmodel import ComputedIntSymbolic, we_are_translated
-from rpython.rlib.rarithmetic import ovfcheck
-from rpython.rlib.rarithmetic import r_longlong, r_ulonglong, r_uint
-from rpython.rlib.rtimer import read_timestamp
-
-import py
-from rpython.tool.ansi_print import ansi_log
-log = py.log.Producer('runner')
-py.log.setconsumer('runner', ansi_log)
-
-IS_32_BIT = r_ulonglong is not r_uint
-
-
-def _from_opaque(opq):
-    return opq._obj.externalobj
-
-_TO_OPAQUE = {}
-
-def _to_opaque(value):
-    try:
-        return value._the_opaque_pointer
-    except AttributeError:
-        op = lltype.opaqueptr(_TO_OPAQUE[value.__class__], 'opaque',
-                              externalobj=value)
-        value._the_opaque_pointer = op
-        return op
-
-def _normalize(value):
-    if isinstance(value, lltype._ptr):
-        value = lltype.top_container(value._obj)
-    return value
-
-def from_opaque_string(s):
-    if isinstance(s, str):
-        return s
-    elif isinstance(s, ootype._string):
-        return OOSupport.from_rstr(s)
-    else:
-        return LLSupport.from_rstr(s)
-
-FLOAT_ARRAY_TP = lltype.Ptr(lltype.Array(lltype.Float, hints={"nolength": True}))
-def maybe_uncast(TP, array):
-    if array._TYPE.TO.OF != lltype.Float:
-        # array._TYPE.TO._hints.get("uncast_on_llgraph"):
-        array = rffi.cast(TP, array)
-    return array
-
-# a list of argtypes of all operations - couldn't find any and it's
-# very useful.  Note however that the table is half-broken here and
-# there, in ways that are sometimes a bit hard to fix; that's why
-# it is not "official".
-TYPES = {
-    'int_add'         : (('int', 'int'), 'int'),
-    'int_sub'         : (('int', 'int'), 'int'),
-    'int_mul'         : (('int', 'int'), 'int'),
-    'int_floordiv'    : (('int', 'int'), 'int'),
-    'int_mod'         : (('int', 'int'), 'int'),
-    'int_and'         : (('int', 'int'), 'int'),
-    'int_or'          : (('int', 'int'), 'int'),
-    'int_xor'         : (('int', 'int'), 'int'),
-    'int_lshift'      : (('int', 'int'), 'int'),
-    'int_rshift'      : (('int', 'int'), 'int'),
-    'int_lt'          : (('int', 'int'), 'bool'),
-    'int_gt'          : (('int', 'int'), 'bool'),
-    'int_ge'          : (('int', 'int'), 'bool'),
-    'int_le'          : (('int', 'int'), 'bool'),
-    'int_eq'          : (('int', 'int'), 'bool'),
-    'int_ne'          : (('int', 'int'), 'bool'),
-    'int_is_true'     : (('int',), 'bool'),
-    'int_is_zero'     : (('int',), 'bool'),
-    'int_neg'         : (('int',), 'int'),
-    'int_invert'      : (('int',), 'int'),
-    'int_add_ovf'     : (('int', 'int'), 'int'),
-    'int_sub_ovf'     : (('int', 'int'), 'int'),
-    'int_mul_ovf'     : (('int', 'int'), 'int'),
-    'int_force_ge_zero':(('int',), 'int'),
-    'uint_add'        : (('int', 'int'), 'int'),
-    'uint_sub'        : (('int', 'int'), 'int'),
-    'uint_mul'        : (('int', 'int'), 'int'),
-    'uint_lt'         : (('int', 'int'), 'bool'),
-    'uint_le'         : (('int', 'int'), 'bool'),
-    'uint_eq'         : (('int', 'int'), 'bool'),
-    'uint_ne'         : (('int', 'int'), 'bool'),
-    'uint_gt'         : (('int', 'int'), 'bool'),
-    'uint_ge'         : (('int', 'int'), 'bool'),
-    'uint_xor'        : (('int', 'int'), 'int'),
-    'uint_rshift'     : (('int', 'int'), 'int'),
-    'uint_floordiv'   : (('int', 'int'), 'int'),
-    'float_add'       : (('float', 'float'), 'float'),
-    'float_sub'       : (('float', 'float'), 'float'),
-    'float_mul'       : (('float', 'float'), 'float'),
-    'float_truediv'   : (('float', 'float'), 'float'),
-    'float_lt'        : (('float', 'float'), 'bool'),
-    'float_le'        : (('float', 'float'), 'bool'),
-    'float_eq'        : (('float', 'float'), 'bool'),
-    'float_ne'        : (('float', 'float'), 'bool'),
-    'float_gt'        : (('float', 'float'), 'bool'),
-    'float_ge'        : (('float', 'float'), 'bool'),
-    'float_neg'       : (('float',), 'float'),
-    'float_abs'       : (('float',), 'float'),
-    'cast_float_to_int':(('float',), 'int'),
-    'cast_int_to_float':(('int',), 'float'),
-    'same_as'         : (('int',), 'int'),      # could also be ptr=>ptr
-    'new_with_vtable' : (('ref',), 'ref'),
-    'new'             : ((), 'ref'),
-    'new_array'       : (('int',), 'ref'),
-    'oois'            : (('ref', 'ref'), 'bool'),
-    'ooisnot'         : (('ref', 'ref'), 'bool'),
-    'instanceof'      : (('ref',), 'bool'),
-    'subclassof'      : (('ref', 'ref'), 'bool'),
-    'runtimenew'      : (('ref',), 'ref'),
-    'setfield_gc'     : (('ref', 'intorptr'), None),
-    'getfield_gc'     : (('ref',), 'intorptr'),
-    'getfield_gc_pure': (('ref',), 'intorptr'),
-    'setfield_raw'    : (('ref', 'intorptr'), None),
-    'getfield_raw'    : (('ref',), 'intorptr'),
-    'getfield_raw_pure': (('ref',), 'intorptr'),
-    'setarrayitem_gc' : (('ref', 'int', 'intorptr'), None),
-    'getarrayitem_gc' : (('ref', 'int'), 'intorptr'),
-    'getarrayitem_gc_pure' : (('ref', 'int'), 'intorptr'),
-    'setarrayitem_raw' : (('ref', 'int', 'intorptr'), None),
-    'getarrayitem_raw' : (('ref', 'int'), 'intorptr'),
-    'getarrayitem_raw_pure' : (('ref', 'int'), 'intorptr'),
-    'arraylen_gc'     : (('ref',), 'int'),
-    'call'            : (('ref', 'varargs'), 'intorptr'),
-    'call_assembler'  : (('varargs',), 'intorptr'),
-    'cond_call_gc_wb' : (('ptr', 'ptr'), None),
-    'cond_call_gc_wb_array': (('ptr', 'int', 'ptr'), None),
-    'oosend'          : (('varargs',), 'intorptr'),
-    'oosend_pure'     : (('varargs',), 'intorptr'),
-    'guard_true'      : (('bool',), None),
-    'guard_false'     : (('bool',), None),
-    'guard_value'     : (('int', 'int'), None),
-    'guard_class'     : (('ref', 'ref'), None),
-    'guard_no_exception'   : ((), None),
-    'guard_exception'      : (('ref',), 'ref'),
-    'guard_no_overflow'    : ((), None),
-    'guard_overflow'       : ((), None),
-    'guard_nonnull'        : (('ref',), None),
-    'guard_isnull'        : (('ref',), None),
-    'guard_nonnull_class' : (('ref', 'ref'), None),
-    'newstr'          : (('int',), 'ref'),
-    'strlen'          : (('ref',), 'int'),
-    'strgetitem'      : (('ref', 'int'), 'int'),
-    'strsetitem'      : (('ref', 'int', 'int'), None),
-    'newunicode'      : (('int',), 'ref'),
-    'unicodelen'      : (('ref',), 'int'),
-    'unicodegetitem'  : (('ref', 'int'), 'int'),
-    'unicodesetitem'  : (('ref', 'int', 'int'), 'int'),
-    'cast_ptr_to_int' : (('ref',), 'int'),
-    'cast_int_to_ptr' : (('int',), 'ref'),
-    'debug_merge_point': (('ref', 'int', 'int'), None),
-    'force_token'     : ((), 'int'),
-    'call_may_force'  : (('int', 'varargs'), 'intorptr'),
-    'guard_not_forced': ((), None),
-}
-
-# ____________________________________________________________
-
-class CompiledLoop(object):
-    has_been_freed = False
-    invalid = False
-
-    def __init__(self):
-        self.inputargs = []
-        self.operations = []
-
-    def getargtypes(self):
-        return [v.concretetype for v in self.inputargs]
-
-    def __repr__(self):
-        lines = []
-        self.as_text(lines, 1)
-        return 'CompiledLoop %s:\n%s' % (self.inputargs, '\n'.join(lines))
-
-    def as_text(self, lines, indent):
-        for op in self.operations:
-            lines.append('\t'*indent + repr(op))
-
-class Operation(object):
-    result = None
-    descr = None
-    jump_target = None
-    fail_args = None
-
-    def __init__(self, opnum):
-        self.opnum = opnum
-        self.args = []
-
-    def __repr__(self):
-        if self.result is not None:
-            sres = repr0(self.result) + ' = '
-        else:
-            sres = ''
-        return '{%s%s(%s)}' % (sres, self.getopname(),
-                               ', '.join(map(repr0, self.args)))
-
-    def getopname(self):
-        try:
-            return resoperation.opname[self.opnum]
-        except KeyError:
-            return '<%d>' % self.opnum
-
-    def is_guard(self):
-        return rop._GUARD_FIRST <= self.opnum <= rop._GUARD_LAST
-
-    def is_final(self):
-        return rop._FINAL_FIRST <= self.opnum <= rop._FINAL_LAST
-
-def repr0(x):
-    if isinstance(x, list):
-        return '[' + ', '.join(repr0(y) for y in x) + ']'
-    elif isinstance(x, Constant):
-        return '(' + repr0(x.value) + ')'
-    elif isinstance(x, lltype._ptr):
-        x = llmemory.cast_ptr_to_adr(x)
-        if x.ptr:
-            try:
-                container = x.ptr._obj._normalizedcontainer()
-                return '* %s' % (container._TYPE._short_name(),)
-            except AttributeError:
-                return repr(x)
-        else:
-            return 'NULL'
-    else:
-        return repr(x)
-
-def repr_list(lst, types):
-    res_l = []
-    if types and types[-1] == 'varargs':
-        types = types[:-1] + ('int',) * (len(lst) - len(types) + 1)
-    assert len(types) == len(lst)
-    for elem, tp in zip(lst, types):
-        if isinstance(elem, Constant):
-            res_l.append('(%s)' % repr1(elem, tp))
-        else:
-            res_l.append(repr1(elem, tp))
-    return '[%s]' % (', '.join(res_l))
-
-def repr1(x, tp):
-    if tp == "intorptr":
-        TYPE = lltype.typeOf(x)
-        if isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc':
-            tp = "ref"
-        else:
-            tp = "int"
-    if tp == 'int':
-        return str(x)
-    elif tp == 'void':
-        return '---'
-    elif tp == 'ref':
-        if not x:
-            return '(* None)'
-        if isinstance(x, int):
-            # XXX normalize?
-            ptr = str(llmemory.cast_int_to_adr(x))
-        elif isinstance(ootype.typeOf(x), ootype.OOType):
-            return repr(x)
-        else:
-            if getattr(x, '_fake', None):
-                return repr(x)
-            if lltype.typeOf(x) == llmemory.GCREF:
-                TP = lltype.Ptr(lltype.typeOf(x._obj.container))
-                ptr = lltype.cast_opaque_ptr(TP, x)
-            else:
-                ptr = x
-        try:
-            container = ptr._obj._normalizedcontainer()
-            return '(* %s)' % (container._TYPE._short_name(),)
-        except AttributeError:
-            return '(%r)' % (ptr,)
-    elif tp == 'bool':
-        assert x == 0 or x == 1
-        return str(bool(x))
-    #elif tp == 'fieldname':
-    #    return str(symbolic.TokenToField[x...][1])
-    elif tp == 'float':
-        return str(x)
-    else:
-        raise NotImplementedError("tp = %s" % tp)
-
-_variables = []
-
-def compile_start():
-    del _variables[:]
-    return _to_opaque(CompiledLoop())
-
-def mark_as_free(loop):
-    loop = _from_opaque(loop)
-    assert not loop.has_been_freed
-    loop.has_been_freed = True
-
-def compile_start_int_var(loop):
-    return compile_start_ref_var(loop, lltype.Signed)
-
-def compile_start_float_var(loop):
-    return compile_start_ref_var(loop, longlong.FLOATSTORAGE)
-
-def compile_start_ref_var(loop, TYPE):
-    loop = _from_opaque(loop)
-    assert not loop.operations
-    v = Variable()
-    v.concretetype = TYPE
-    loop.inputargs.append(v)
-    r = len(_variables)
-    _variables.append(v)
-    return r
-
-def compile_started_vars(clt):
-    if not hasattr(clt, '_debug_argtypes'):    # only when compiling the loop
-        argtypes = [v.concretetype for v in _variables]
-        try:
-            clt._debug_argtypes = argtypes
-        except AttributeError:    # when 'clt' is actually a translated
-            pass                  # GcStruct
-
-def compile_add(loop, opnum):
-    loop = _from_opaque(loop)
-    loop.operations.append(Operation(opnum))
-
-def compile_add_descr(loop, ofs, type, arg_types, extrainfo, width):
-    from rpython.jit.backend.llgraph.runner import Descr
-    loop = _from_opaque(loop)
-    op = loop.operations[-1]
-    assert isinstance(type, str) and len(type) == 1
-    op.descr = Descr(ofs, type, arg_types=arg_types, extrainfo=extrainfo, width=width)
-
-def compile_add_descr_arg(loop, ofs, type, arg_types):
-    from rpython.jit.backend.llgraph.runner import Descr
-    loop = _from_opaque(loop)
-    op = loop.operations[-1]
-    assert isinstance(type, str) and len(type) == 1
-    op.args.append(Descr(ofs, type, arg_types=arg_types))
-
-def compile_add_loop_token(loop, descr):
-    if we_are_translated():
-        raise ValueError("CALL_ASSEMBLER not supported")
-    loop = _from_opaque(loop)
-    op = loop.operations[-1]
-    op.descr = weakref.ref(descr)
-
-TARGET_TOKENS = weakref.WeakKeyDictionary()
-
-def compile_add_target_token(loop, descr, clt):
-    # here, 'clt' is the compiled_loop_token of the original loop that
-    # we are compiling
-    loop = _from_opaque(loop)
-    op = loop.operations[-1]
-    descrobj = _normalize(descr)
-    TARGET_TOKENS[descrobj] = loop, len(loop.operations), op.args, clt
-
-def compile_add_var(loop, intvar):
-    loop = _from_opaque(loop)
-    op = loop.operations[-1]
-    op.args.append(_variables[intvar])
-
-def compile_add_int_const(loop, value):
-    compile_add_ref_const(loop, value, lltype.Signed)
-
-def compile_add_float_const(loop, value):
-    compile_add_ref_const(loop, value, longlong.FLOATSTORAGE)
-
-def compile_add_ref_const(loop, value, TYPE):
-    loop = _from_opaque(loop)
-    const = Constant(value)
-    const.concretetype = TYPE
-    op = loop.operations[-1]
-    op.args.append(const)
-
-def compile_add_int_result(loop):
-    return compile_add_ref_result(loop, lltype.Signed)
-
-def compile_add_float_result(loop):
-    return compile_add_ref_result(loop, longlong.FLOATSTORAGE)
-
-def compile_add_ref_result(loop, TYPE):
-    loop = _from_opaque(loop)
-    v = Variable()
-    v.concretetype = TYPE
-    op = loop.operations[-1]
-    op.result = v
-    r = len(_variables)
-    _variables.append(v)
-    return r
-
-def compile_add_jump_target(loop, targettoken, source_clt):
-    loop = _from_opaque(loop)
-    descrobj = _normalize(targettoken)
-    (loop_target, target_opindex, target_inputargs, target_clt
-        ) = TARGET_TOKENS[descrobj]
-    #
-    try:
-        assert source_clt._debug_argtypes == target_clt._debug_argtypes
-    except AttributeError:   # when translated
-        pass
-    #
-    op = loop.operations[-1]
-    op.jump_target = loop_target
-    op.jump_target_opindex = target_opindex
-    op.jump_target_inputargs = target_inputargs
-    assert op.opnum == rop.JUMP
-    assert [v.concretetype for v in op.args] == (
-           [v.concretetype for v in target_inputargs])
-    #
-    if loop_target == loop:
-        log.info("compiling new loop")
-    else:
-        log.info("compiling new bridge")
-
-def compile_add_guard_jump_target(loop, loop_target):
-    loop = _from_opaque(loop)
-    loop_target = _from_opaque(loop_target)
-    op = loop.operations[-1]
-    assert op.is_guard()
-    op.jump_target = loop_target
-
-def compile_add_fail(loop, fail_index):
-    loop = _from_opaque(loop)
-    index = len(loop.operations)-1
-    op = loop.operations[index]
-    op.fail_index = fail_index
-    return index
-
-def compile_add_fail_arg(loop, intvar):
-    loop = _from_opaque(loop)
-    op = loop.operations[-1]
-    if op.fail_args is None:
-        op.fail_args = []
-    if intvar == -1:
-        op.fail_args.append(None)
-    else:
-        op.fail_args.append(_variables[intvar])
-
-def compile_redirect_fail(old_loop, old_index, new_loop):
-    old_loop = _from_opaque(old_loop)
-    new_loop = _from_opaque(new_loop)
-    guard_op = old_loop.operations[old_index]
-    assert guard_op.is_guard()
-    guard_op.jump_target = new_loop
-    # check that the bridge's inputargs are of the correct number and
-    # kind for the guard
-    if guard_op.fail_args is not None:
-        argkinds = [v.concretetype for v in guard_op.fail_args if v]
-    else:
-        argkinds = []
-    assert argkinds == [v.concretetype for v in new_loop.inputargs]
-
-# ------------------------------
-
-class Frame(object):
-    OPHANDLERS = [None] * (rop._LAST+1)
-
-    def __init__(self, cpu):
-        self.verbose = False
-        self.cpu = cpu
-        self.opindex = 1
-        self._forced = False
-        self._may_force = -1
-
-    def getenv(self, v):
-        from rpython.jit.backend.llgraph.runner import Descr
-        if isinstance(v, Constant):
-            return v.value
-        elif isinstance(v, Descr):
-            return v
-        else:
-            return self.env[v]
-
-    def _populate_fail_args(self, op, skip=None):
-        fail_args = []
-        if op.fail_args:
-            for fail_arg in op.fail_args:
-                if fail_arg is None:
-                    fail_args.append(None)
-                elif fail_arg is skip:
-                    fail_args.append(fail_arg.concretetype._defl())
-                else:
-                    fail_args.append(self.getenv(fail_arg))
-        self.fail_args = fail_args
-        self.fail_index = op.fail_index
-
-    def execute(self):
-        """Execute all operations in a loop,
-        possibly following to other loops as well.
-        """
-        global _last_exception
-        assert _last_exception is None, "exception left behind"
-        verbose = True
-        self.opindex = 0
-        while True:
-            assert not self.loop.has_been_freed
-            op = self.loop.operations[self.opindex]
-            args = [self.getenv(v) for v in op.args]
-            if not op.is_final():
-                try:
-                    result = self.execute_operation(op.opnum, args, op.descr,
-                                                    verbose)
-                except GuardFailed:
-                    assert op.is_guard()
-                    _stats.exec_conditional_jumps += 1
-                    if op.jump_target is not None:
-                        # a patched guard, pointing to further code
-                        if op.fail_args:
-                            args = [self.getenv(v) for v in op.fail_args if v]
-                        else:
-                            args = []
-                        assert len(op.jump_target.inputargs) == len(args)
-                        self.env = dict(zip(op.jump_target.inputargs, args))
-                        self.loop = op.jump_target
-                        self.opindex = 0
-                        continue
-                    else:
-                        self._populate_fail_args(op)
-                        # a non-patched guard
-                        if self.verbose:
-                            log.trace('failed: %s' % (
-                                ', '.join(map(str, fail_args)),))
-                        return op.fail_index
-                #verbose = self.verbose
-                assert (result is None) == (op.result is None)
-                if op.result is not None:
-                    RESTYPE = op.result.concretetype
-                    if RESTYPE is lltype.Signed:
-                        x = self.as_int(result)
-                    elif RESTYPE is llmemory.GCREF:
-                        x = self.as_ptr(result)
-                    elif RESTYPE is ootype.Object:
-                        x = self.as_object(result)
-                    elif RESTYPE is longlong.FLOATSTORAGE:
-                        x = self.as_floatstorage(result)
-                    else:
-                        raise Exception("op.result.concretetype is %r"
-                                        % (RESTYPE,))
-                    self.env[op.result] = x
-                self.opindex += 1
-                continue
-            if op.opnum == rop.JUMP:
-                inputargs = op.jump_target_inputargs
-                assert len(inputargs) == len(args)
-                self.env = dict(zip(inputargs, args))
-                self.loop = op.jump_target
-                self.opindex = op.jump_target_opindex
-                _stats.exec_jumps += 1
-            elif op.opnum == rop.FINISH:
-                if self.verbose:
-                    log.trace('finished: %s' % (
-                        ', '.join(map(str, args)),))
-                self.fail_args = args
-                return op.fail_index
-
-            else:
-                assert 0, "unknown final operation %d" % (op.opnum,)
-
-    def execute_operation(self, opnum, values, descr, verbose):
-        """Execute a single operation.
-        """
-        ophandler = self.OPHANDLERS[opnum]
-        if ophandler is None:
-            self._define_impl(opnum)
-            ophandler = self.OPHANDLERS[opnum]
-            assert ophandler is not None, "missing impl for op %d" % opnum
-        opname = resoperation.opname[opnum].lower()
-        exec_counters = _stats.exec_counters
-        exec_counters[opname] = exec_counters.get(opname, 0) + 1
-        for i in range(len(values)):
-            if isinstance(values[i], ComputedIntSymbolic):
-                values[i] = values[i].compute_fn()
-        res = NotImplemented
-        try:
-            res = ophandler(self, descr, *values)
-        finally:
-            if 0:     # if verbose:
-                argtypes, restype = TYPES[opname]
-                if res is None:
-                    resdata = ''
-                elif res is NotImplemented:
-                    resdata = '*fail*'
-                else:
-                    resdata = '-> ' + repr1(res, restype)
-                # fish the types
-                log.cpu('\t%s %s %s' % (opname, repr_list(values, argtypes),
-                                        resdata))
-        return res
-
-    def as_int(self, x):
-        return cast_to_int(x)
-
-    def as_ptr(self, x):
-        return cast_to_ptr(x)
-
-    def as_object(self, x):
-        return ootype.cast_to_object(x)
-
-    def as_floatstorage(self, x):
-        return cast_to_floatstorage(x)
-
-    def log_progress(self):
-        count = sum(_stats.exec_counters.values())
-        count_jumps = _stats.exec_jumps
-        log.trace('ran %d operations, %d jumps' % (count, count_jumps))
-
-    # ----------
-
-    @classmethod
-    def _define_impl(cls, opnum):
-        opname = resoperation.opname[opnum]
-        try:
-            op = getattr(cls, 'op_' + opname.lower())   # op_guard_true etc.
-        except AttributeError:
-            try:
-                impl = globals()['do_' + opname.lower()]  # do_arraylen_gc etc.
-                def op(self, descr, *args):
-                    if descr is None:
-                        return impl(*args)
-                    else:
-                        return impl(descr, *args)
-            except KeyError:
-                op = cls._make_impl_from_blackhole_interp(opname)
-        cls.OPHANDLERS[opnum] = op
-
-    @classmethod
-    def _make_impl_from_blackhole_interp(cls, opname):
-        from rpython.jit.metainterp.blackhole import BlackholeInterpreter
-        name = 'bhimpl_' + opname.lower()
-        func = BlackholeInterpreter.__dict__[name]
-        for argtype in func.argtypes:
-            assert argtype in ('i', 'r', 'f')
-        #
-        def _op_default_implementation(self, descr, *args):
-            # for all operations implemented in the blackhole interpreter
-            return func(*args)
-        #
-        return _op_default_implementation
-
-    def op_label(self, _, *args):
-        op = self.loop.operations[self.opindex]
-        assert op.opnum == rop.LABEL
-        assert len(op.args) == len(args)
-        newenv = {}
-        for v, value in zip(op.args, args):
-            newenv[v] = value
-        self.env = newenv
-
-    def op_debug_merge_point(self, _, *args):
-        from rpython.jit.metainterp.warmspot import get_stats
-        try:
-            stats = get_stats()
-        except AttributeError:
-            pass
-        else:
-            stats.add_merge_point_location(args[1:])
-        pass
-
-    def op_guard_true(self, _, value):
-        if not value:
-            raise GuardFailed
-
-    def op_guard_false(self, _, value):
-        if value:
-            raise GuardFailed
-
-    op_guard_nonnull = op_guard_true
-    op_guard_isnull  = op_guard_false
-
-    def op_guard_class(self, _, value, expected_class):
-        value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, value)
-        expected_class = llmemory.cast_adr_to_ptr(
-            llmemory.cast_int_to_adr(expected_class),
-            rclass.CLASSTYPE)
-        if value.typeptr != expected_class:
-            raise GuardFailed
-
-    def op_guard_nonnull_class(self, _, value, expected_class):
-        if not value:
-            raise GuardFailed
-        self.op_guard_class(_, value, expected_class)
-
-    def op_guard_value(self, _, value, expected_value):
-        if value != expected_value:
-            raise GuardFailed
-
-    def op_guard_no_exception(self, _):
-        if _last_exception:
-            raise GuardFailed
-
-    def _check_exception(self, expected_exception):
-        global _last_exception
-        expected_exception = self._cast_exception(expected_exception)
-        assert expected_exception
-        exc = _last_exception
-        if exc:
-            got = exc.args[0]
-            # exact match!
-            if got != expected_exception:
-                return False
-            return True
-        else:
-            return False
-
-    def _cast_exception(self, exception):
-        return llmemory.cast_adr_to_ptr(
-            llmemory.cast_int_to_adr(exception),
-            rclass.CLASSTYPE)
-
-    def _issubclass(self, cls1, cls2):
-        return rclass.ll_issubclass(cls1, cls2)
-
-    def op_guard_exception(self, _, expected_exception):
-        global _last_exception
-        if not self._check_exception(expected_exception):
-            raise GuardFailed
-        res = _last_exception[1]
-        _last_exception = None
-        return res
-
-    def op_guard_no_overflow(self, _):
-        flag = self.overflow_flag
-        del self.overflow_flag
-        if flag:
-            raise GuardFailed
-
-    def op_guard_overflow(self, _):
-        flag = self.overflow_flag
-        del self.overflow_flag
-        if not flag:
-            raise GuardFailed
-
-    def op_int_add_ovf(self, _, x, y):
-        try:
-            z = ovfcheck(x + y)
-        except OverflowError:
-            ovf = True
-            z = 0
-        else:
-            ovf = False
-        self.overflow_flag = ovf
-        return z
-
-    def op_int_sub_ovf(self, _, x, y):
-        try:
-            z = ovfcheck(x - y)
-        except OverflowError:
-            ovf = True
-            z = 0
-        else:
-            ovf = False
-        self.overflow_flag = ovf
-        return z
-
-    def op_int_mul_ovf(self, _, x, y):
-        try:
-            z = ovfcheck(x * y)
-        except OverflowError:
-            ovf = True
-            z = 0
-        else:
-            ovf = False
-        self.overflow_flag = ovf
-        return z
-
-    def op_keepalive(self, _, x):
-        pass
-
-    # ----------
-    # delegating to the builtins do_xxx() (done automatically for simple cases)
-
-    def op_getarrayitem_gc(self, arraydescr, array, index):
-        if arraydescr.typeinfo == REF:
-            return do_getarrayitem_gc_ptr(array, index)
-        elif arraydescr.typeinfo == INT:
-            return do_getarrayitem_gc_int(array, index)
-        elif arraydescr.typeinfo == FLOAT:
-            return do_getarrayitem_gc_float(array, index)
-        else:
-            raise NotImplementedError
-
-    op_getarrayitem_gc_pure = op_getarrayitem_gc
-
-    def op_getarrayitem_raw(self, arraydescr, array, index):
-        if arraydescr.typeinfo == REF:
-            raise NotImplementedError("getarrayitem_raw -> gcref")
-        elif arraydescr.typeinfo == INT:
-            return do_getarrayitem_raw_int(array, index, arraydescr.ofs)
-        elif arraydescr.typeinfo == FLOAT:
-            return do_getarrayitem_raw_float(array, index)
-        else:
-            raise NotImplementedError
-
-    op_getarrayitem_raw_pure = op_getarrayitem_raw
-
-    def op_getfield_gc(self, fielddescr, struct):
-        if fielddescr.typeinfo == REF:
-            return do_getfield_gc_ptr(struct, fielddescr.ofs)
-        elif fielddescr.typeinfo == INT:
-            return do_getfield_gc_int(struct, fielddescr.ofs)
-        elif fielddescr.typeinfo == FLOAT:
-            return do_getfield_gc_float(struct, fielddescr.ofs)
-        else:
-            raise NotImplementedError
-
-    op_getfield_gc_pure = op_getfield_gc
-
-    def op_getfield_raw(self, fielddescr, struct):
-        if fielddescr.typeinfo == REF:
-            return do_getfield_raw_ptr(struct, fielddescr.ofs)
-        elif fielddescr.typeinfo == INT:
-            return do_getfield_raw_int(struct, fielddescr.ofs)
-        elif fielddescr.typeinfo == FLOAT:
-            return do_getfield_raw_float(struct, fielddescr.ofs)
-        else:
-            raise NotImplementedError
-
-    op_getfield_raw_pure = op_getfield_raw
-
-    def op_raw_store(self, arraydescr, addr, offset, value):
-        if arraydescr.typeinfo == REF:
-            raise AssertionError("cannot store GC pointer in raw storage")
-        elif arraydescr.typeinfo == INT:
-            do_raw_store_int(addr, offset, arraydescr.ofs, value)
-        elif arraydescr.typeinfo == FLOAT:
-            do_raw_store_float(addr, offset, value)
-        else:
-            raise NotImplementedError
-
-    def op_raw_load(self, arraydescr, addr, offset):
-        if arraydescr.typeinfo == REF: 
-            raise AssertionError("cannot store GC pointer in raw storage")
-        elif arraydescr.typeinfo == INT:
-            return do_raw_load_int(addr, offset, arraydescr.ofs)
-        elif arraydescr.typeinfo == FLOAT:
-            return do_raw_load_float(addr, offset)
-        else:
-            raise NotImplementedError
-
-    def op_new(self, size):
-        return do_new(size.ofs)
-
-    def op_new_with_vtable(self, descr, vtable):
-        assert descr is None
-        descr = heaptracker.vtable2descr(self.cpu, vtable)
-        result = do_new(descr.ofs)
-        value = lltype.cast_opaque_ptr(rclass.OBJECTPTR, result)
-        value.typeptr = cast_from_int(rclass.CLASSTYPE, vtable)
-        return result
-
-    def op_setarrayitem_gc(self, arraydescr, array, index, newvalue):
-        if arraydescr.typeinfo == REF:
-            do_setarrayitem_gc_ptr(array, index, newvalue)
-        elif arraydescr.typeinfo == INT:
-            do_setarrayitem_gc_int(array, index, newvalue)
-        elif arraydescr.typeinfo == FLOAT:
-            do_setarrayitem_gc_float(array, index, newvalue)
-        else:
-            raise NotImplementedError
-
-    def op_setarrayitem_raw(self, arraydescr, array, index, newvalue):
-        if arraydescr.typeinfo == REF:
-            raise NotImplementedError("setarrayitem_raw <- gcref")
-        elif arraydescr.typeinfo == INT:
-            do_setarrayitem_raw_int(array, index, newvalue, arraydescr.ofs)
-        elif arraydescr.typeinfo == FLOAT:
-            do_setarrayitem_raw_float(array, index, newvalue)
-        else:
-            raise NotImplementedError
-
-    def op_getinteriorfield_gc(self, descr, array, index):
-        if descr.typeinfo == REF:
-            return do_getinteriorfield_gc_ptr(array, index, descr.ofs)
-        elif descr.typeinfo == INT:
-            return do_getinteriorfield_gc_int(array, index, descr.ofs)
-        elif descr.typeinfo == FLOAT:
-            return do_getinteriorfield_gc_float(array, index, descr.ofs)
-        else:
-            raise NotImplementedError
-
-    def op_getinteriorfield_raw(self, descr, array, index):
-        if descr.typeinfo == REF:
-            return do_getinteriorfield_raw_ptr(array, index, descr.width, descr.ofs)
-        elif descr.typeinfo == INT: