Author: Manuel Jacob
Branch: refactor-str-types
Changeset: r65866:a8ec1d207404
Date: 2013-07-31 22:19 +0200
http://bitbucket.org/pypy/pypy/changeset/a8ec1d207404/

Log:    hg merge default

diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py
--- a/lib_pypy/_curses.py
+++ b/lib_pypy/_curses.py
@@ -966,7 +966,7 @@
     r, g, b = ffi.new("short *"), ffi.new("short *"), ffi.new("short *")
     if lib.color_content(color, r, g, b) == lib.ERR:
         raise error("Argument 1 was out of range. Check value of COLORS.")
-    return (r, g, b)
+    return (r[0], g[0], b[0])
 
 
 def color_pair(n):
@@ -1121,6 +1121,7 @@
         term = ffi.NULL
     err = ffi.new("int *")
     if lib.setupterm(term, fd, err) == lib.ERR:
+        err = err[0]
         if err == 0:
             raise error("setupterm: could not find terminal")
         elif err == -1:
diff --git a/pypy/doc/release-2.1.0.rst b/pypy/doc/release-2.1.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-2.1.0.rst
@@ -0,0 +1,89 @@
+============================
+PyPy 2.1 - Considered ARMful
+============================
+
+We're pleased to announce PyPy 2.1, which targets version 2.7.3 of the Python
+language. This is the first release with official support for ARM processors 
in the JIT.
+This release also contains several bugfixes and performance improvements. 
+
+You can download the PyPy 2.1 release here:
+
+    http://pypy.org/download.html
+
+We would like to thank the `Raspberry Pi Foundation`_ for supporting the work
+to finish PyPy's ARM support.
+
+.. _`Raspberry Pi Foundation`: http://www.raspberrypi.org
+
+The first beta of PyPy3 2.1, targetting version 3 of the Python language, was
+just released, more details can be found `here`_.
+
+.. _`here`: http://morepypy.blogspot.com/2013/07/pypy3-21-beta-1.html
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy 2.1 and cpython 2.7.2`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+This release supports x86 machines running Linux 32/64, Mac OS X 64 or Windows
+32. This release also supports ARM machines running Linux 32bit - anything with
+``ARMv6`` (like the Raspberry Pi) or ``ARMv7`` (like the Beagleboard,
+Chromebook, Cubieboard, etc.) that supports ``VFPv3`` should work. Both
+hard-float ``armhf/gnueabihf`` and soft-float ``armel/gnueabi`` builds are
+provided. ``armhf`` builds for Raspbian are created using the Raspberry Pi
+`custom cross-compilation toolchain <https://github.com/raspberrypi>`_
+based on ``gcc-arm-linux-gnueabihf`` and should work on ``ARMv6`` and
+``ARMv7`` devices running Debian or Raspbian. ``armel`` builds are built
+using the ``gcc-arm-linux-gnuebi`` toolchain provided by Ubuntu and
+currently target ``ARMv7``.
+
+Windows 64 work is still stalling, we would welcome a volunteer
+to handle that.
+
+.. _`pypy 2.1 and cpython 2.7.2`: http://speed.pypy.org
+
+Highlights
+==========
+
+* JIT support for ARM, architecture versions 6 and 7, hard- and soft-float ABI
+
+* Stacklet support for ARM
+
+* Support for os.statvfs and os.fstatvfs on unix systems
+
+* Improved logging performance
+
+* Faster sets for objects
+
+* Interpreter improvements
+
+* During packaging, compile the CFFI based TK extension
+
+* Pickling of numpy arrays and dtypes 
+
+* Subarrays for numpy
+
+* Bugfixes to numpy
+
+* Bugfixes to cffi and ctypes
+
+* Bugfixes to the x86 stacklet support
+
+* Fixed issue `1533`_: fix an RPython-level OverflowError for 
space.float_w(w_big_long_number). 
+
+* Fixed issue `1552`_: GreenletExit should inherit from BaseException.
+
+* Fixed issue `1537`_: numpypy __array_interface__
+  
+* Fixed issue `1238`_: Writing to an SSL socket in PyPy sometimes failed with 
a "bad write retry" message.
+
+.. _`1533`: https://bugs.pypy.org/issue1533
+.. _`1552`: https://bugs.pypy.org/issue1552
+.. _`1537`: https://bugs.pypy.org/issue1537
+.. _`1238`: https://bugs.pypy.org/issue1238
+
+Cheers,
+
+David Schneider for the PyPy team.
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -52,3 +52,9 @@
 .. branch: fast-slowpath
 Added an abstraction for functions with a fast and slow path in the JIT. This
 speeds up list.append() and list.pop().
+
+.. branch: curses_fixes
+
+.. branch: foldable-getarrayitem-indexerror
+Constant-fold reading out of constant tuples in PyPy.
+
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -31,7 +31,7 @@
 # Magic numbers for the bytecode version in code objects.
 # See comments in pypy/module/imp/importing.
 cpython_magic, = struct.unpack("<i", imp.get_magic())   # host magic number
-default_magic = (168686339+2) | 0x0a0d0000              # this PyPy's magic
+default_magic = (0xf303 + 6) | 0x0a0d0000               # this PyPy's magic
                                                         # (from CPython 2.7.0)
 
 # cpython_code_signature helper
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -833,21 +833,16 @@
 """
 
 # picking a magic number is a mess.  So far it works because we
-# have only one extra opcode, which bumps the magic number by +2, and CPython
-# leaves a gap of 10 when it increases
-# its own magic number.  To avoid assigning exactly the same numbers
-# as CPython we always add a +2.  We'll have to think again when we
-# get three more new opcodes
+# have only one extra opcode which might or might not be present.
+# CPython leaves a gap of 10 when it increases its own magic number.
+# To avoid assigning exactly the same numbers as CPython, we can pick
+# any number between CPython + 2 and CPython + 9.  Right now,
+# default_magic = CPython + 6.
 #
-#  * CALL_METHOD            +2
-#
-# In other words:
-#
-#     default_magic        -- used by CPython without the -U option
-#     default_magic + 1    -- used by CPython with the -U option
-#     default_magic + 2    -- used by PyPy without any extra opcode
-#     ...
-#     default_magic + 5    -- used by PyPy with both extra opcodes
+#     default_magic - 6    -- used by CPython without the -U option
+#     default_magic - 5    -- used by CPython with the -U option
+#     default_magic        -- used by PyPy without the CALL_METHOD opcode
+#     default_magic + 2    -- used by PyPy with the CALL_METHOD opcode
 #
 from pypy.interpreter.pycode import default_magic
 MARSHAL_VERSION_FOR_PYC = 2
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -37,7 +37,8 @@
         from pypy.module.micronumpy.arrayimpl import concrete, scalar
 
         if not shape:
-            impl = scalar.Scalar(dtype.base)
+            w_val = dtype.base.coerce(space, space.wrap(0))
+            impl = scalar.Scalar(dtype.base, w_val)
         else:
             strides, backstrides = calc_strides(shape, dtype.base, order)
             impl = concrete.ConcreteArray(shape, dtype.base, order, strides,
@@ -79,6 +80,8 @@
 
         if w_val is not None:
             w_val = dtype.coerce(space, w_val)
+        else:
+            w_val = dtype.coerce(space, space.wrap(0))
         return W_NDimArray(scalar.Scalar(dtype, w_val))
 
 
diff --git a/pypy/module/micronumpy/interp_boxes.py 
b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -205,6 +205,7 @@
     descr_neg = _unaryop_impl("negative")
     descr_abs = _unaryop_impl("absolute")
     descr_invert = _unaryop_impl("invert")
+    descr_conjugate = _unaryop_impl("conjugate")
 
     def descr_divmod(self, space, w_other):
         w_quotient = self.descr_div(space, w_other)
@@ -517,6 +518,7 @@
     all = interp2app(W_GenericBox.descr_all),
     ravel = interp2app(W_GenericBox.descr_ravel),
     round = interp2app(W_GenericBox.descr_round),
+    conjugate = interp2app(W_GenericBox.descr_conjugate),
     view = interp2app(W_GenericBox.descr_view),
 )
 
diff --git a/pypy/module/micronumpy/test/test_complex.py 
b/pypy/module/micronumpy/test/test_complex.py
--- a/pypy/module/micronumpy/test/test_complex.py
+++ b/pypy/module/micronumpy/test/test_complex.py
@@ -400,6 +400,7 @@
 
         assert conj is conjugate
         assert conj(c0) == c0
+        assert c0.conjugate() == c0
         assert conj(c1) == complex(1, -2)
         assert conj(1) == 1
         assert conj(-3) == -3
@@ -625,6 +626,8 @@
 
         a = array([1 + 2j, 1 - 2j])
         assert (a.conj() == [1 - 2j, 1 + 2j]).all()
+        a = array([1,2,3.4J],dtype=complex)
+        assert a[2].conjugate() == 0-3.4j
 
     def test_math(self):
         if self.isWindows:
diff --git a/pypy/module/micronumpy/test/test_numarray.py 
b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -264,6 +264,8 @@
         assert a.dtype is dtype(int)
         a = ndarray([], dtype=float)
         assert a.shape == ()
+        # test uninitialized value crash?
+        assert len(str(a)) > 0
 
     def test_ndmin(self):
         from numpypy import array
diff --git a/pypy/module/micronumpy/tool/numready/main.py 
b/pypy/module/micronumpy/tool/numready/main.py
--- a/pypy/module/micronumpy/tool/numready/main.py
+++ b/pypy/module/micronumpy/tool/numready/main.py
@@ -78,6 +78,11 @@
         items.add(Item(name, kind, subitems))
     return items
 
+def get_version_str(python):
+    args = [python, '-c', 'import sys; print sys.version']
+    lines = subprocess.check_output(args).splitlines()
+    return lines[0]
+
 def split(lst):
     SPLIT = 5
     lgt = len(lst) // SPLIT + 1
@@ -93,6 +98,7 @@
 def main(argv):
     cpy_items = find_numpy_items("/usr/bin/python")
     pypy_items = find_numpy_items(argv[1], "numpypy")
+    ver = get_version_str(argv[1])
     all_items = []
 
     msg = "{:d}/{:d} names".format(len(pypy_items), len(cpy_items)) + " "
@@ -113,7 +119,8 @@
     env = jinja2.Environment(
         loader=jinja2.FileSystemLoader(os.path.dirname(__file__))
     )
-    html = 
env.get_template("page.html").render(all_items=split(sorted(all_items)), 
msg=msg)
+    html = 
env.get_template("page.html").render(all_items=split(sorted(all_items)),
+             msg=msg, ver=ver)
     if len(argv) > 2:
         with open(argv[2], 'w') as f:
             f.write(html.encode("utf-8"))
diff --git a/pypy/module/micronumpy/tool/numready/page.html 
b/pypy/module/micronumpy/tool/numready/page.html
--- a/pypy/module/micronumpy/tool/numready/page.html
+++ b/pypy/module/micronumpy/tool/numready/page.html
@@ -34,6 +34,7 @@
     </head>
     <body>
         <h1>NumPyPy Status</h1>
+        <h3>Version: {{ ver }}</h3>
         <h3>Overall: {{ msg }}</h3>
         <table>
             <thead>
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py 
b/pypy/module/pypyjit/test_pypy_c/test_containers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_containers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -209,6 +209,22 @@
         opnames = log.opnames(loop.allops())
         assert opnames.count('new_with_vtable') == 0
 
+    def test_constfold_tuple(self):
+        code = """if 1:
+        tup = tuple(range(10000))
+        l = [1, 2, 3, 4, 5, 6, "a"]
+        def main(n):
+            while n > 0:
+                sub = tup[1]  # ID: getitem
+                l[1] = n # kill cache of tup[1]
+                n -= sub
+        """
+        log = self.run(code, [1000])
+        loop, = log.loops_by_filename(self.filepath)
+        ops = loop.ops_by_id('getitem', include_guard_not_invalidated=False)
+        assert log.opnames(ops) == []
+
+
     def test_specialised_tuple(self):
         def main(n):
             import pypyjit
diff --git a/pypy/module/test_lib_pypy/test_curses.py 
b/pypy/module/test_lib_pypy/test_curses.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/test_curses.py
@@ -0,0 +1,48 @@
+from lib_pypy import _curses
+
+import pytest
+
+lib = _curses.lib
+
+
+def test_color_content(monkeypatch):
+    def lib_color_content(color, r, g, b):
+        r[0], g[0], b[0] = 42, 43, 44
+        return lib.OK
+
+    monkeypatch.setattr(_curses, '_ensure_initialised_color', lambda: None)
+    monkeypatch.setattr(lib, 'color_content', lib_color_content)
+
+    assert _curses.color_content(None) == (42, 43, 44)
+
+
+def test_setupterm(monkeypatch):
+    def make_setupterm(err_no):
+        def lib_setupterm(term, fd, err):
+            err[0] = err_no
+
+            return lib.ERR
+
+        return lib_setupterm
+
+    monkeypatch.setattr(_curses, '_initialised_setupterm', False)
+    monkeypatch.setattr(lib, 'setupterm', make_setupterm(0))
+
+    with pytest.raises(Exception) as exc_info:
+        _curses.setupterm()
+
+    assert "could not find terminal" in exc_info.value.args[0]
+
+    monkeypatch.setattr(lib, 'setupterm', make_setupterm(-1))
+
+    with pytest.raises(Exception) as exc_info:
+        _curses.setupterm()
+
+    assert "could not find terminfo database" in exc_info.value.args[0]
+
+    monkeypatch.setattr(lib, 'setupterm', make_setupterm(42))
+
+    with pytest.raises(Exception) as exc_info:
+        _curses.setupterm()
+
+    assert "unknown error" in exc_info.value.args[0]
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -472,6 +472,14 @@
         return space.wrap(1)
 
     def coerce(space, w_obj1, w_obj2):
+        w_res = space.try_coerce(w_obj1, w_obj2)
+        if w_res is None:
+            raise OperationError(space.w_TypeError,
+                                 space.wrap("coercion failed"))
+        return w_res
+
+    def try_coerce(space, w_obj1, w_obj2):
+        """Returns a wrapped 2-tuple or a real None if it failed."""
         w_typ1 = space.type(w_obj1)
         w_typ2 = space.type(w_obj2)
         w_left_src, w_left_impl = space.lookup_in_type_where(w_typ1, 
'__coerce__')
@@ -488,8 +496,7 @@
         if w_res is None or space.is_w(w_res, space.w_None):
             w_res = _invoke_binop(space, w_right_impl, w_obj2, w_obj1)
             if w_res is None  or space.is_w(w_res, space.w_None):
-                raise OperationError(space.w_TypeError,
-                                     space.wrap("coercion failed"))
+                return None
             if (not space.isinstance_w(w_res, space.w_tuple) or
                 space.len_w(w_res) != 2):
                 raise OperationError(space.w_TypeError,
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -702,11 +702,13 @@
 find_jmp = jit.JitDriver(greens = [], reds = 'auto', name = 'list.find')
 
 class ListStrategy(object):
-    sizehint = -1
 
     def __init__(self, space):
         self.space = space
 
+    def get_sizehint(self):
+        return -1
+
     def init_from_list_w(self, w_list, list_w):
         raise NotImplementedError
 
@@ -894,7 +896,7 @@
         else:
             strategy = self.space.fromcache(ObjectListStrategy)
 
-        storage = strategy.get_empty_storage(self.sizehint)
+        storage = strategy.get_empty_storage(self.get_sizehint())
         w_list.strategy = strategy
         w_list.lstorage = storage
 
@@ -974,6 +976,9 @@
         self.sizehint = sizehint
         ListStrategy.__init__(self, space)
 
+    def get_sizehint(self):
+        return self.sizehint
+
     def _resize_hint(self, w_list, hint):
         assert hint >= 0
         self.sizehint = hint
diff --git a/pypy/tool/release/force-builds.py 
b/pypy/tool/release/force-builds.py
--- a/pypy/tool/release/force-builds.py
+++ b/pypy/tool/release/force-builds.py
@@ -19,6 +19,7 @@
 BUILDERS = [
     'own-linux-x86-32',
     'own-linux-x86-64',
+    'own-linux-armhf',
 #    'own-macosx-x86-32',
 #    'pypy-c-app-level-linux-x86-32',
 #    'pypy-c-app-level-linux-x86-64',
diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py 
b/rpython/jit/backend/llsupport/test/test_gc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_gc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py
@@ -88,7 +88,7 @@
             else:
                 assert nos ==  [0, 1, 25]
         elif self.cpu.backend_name.startswith('arm'):
-            assert nos == [9, 10, 47]
+            assert nos == [0, 1, 47]
         else:
             raise Exception("write the data here")
         assert frame.jf_frame[nos[0]]
diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py
--- a/rpython/jit/backend/model.py
+++ b/rpython/jit/backend/model.py
@@ -187,10 +187,6 @@
         # with Voids removed
         raise NotImplementedError
 
-    def methdescrof(self, SELFTYPE, methname):
-        # must return a subclass of history.AbstractMethDescr
-        raise NotImplementedError
-
     def typedescrof(self, TYPE):
         raise NotImplementedError
 
diff --git a/rpython/jit/backend/test/test_ll_random.py 
b/rpython/jit/backend/test/test_ll_random.py
--- a/rpython/jit/backend/test/test_ll_random.py
+++ b/rpython/jit/backend/test/test_ll_random.py
@@ -502,6 +502,7 @@
 # 3. raising call and wrong guard_exception
 # 4. raising call and guard_no_exception
 # 5. non raising call and guard_exception
+# (6. test of a cond_call, always non-raising and guard_no_exception)
 
 class BaseCallOperation(test_random.AbstractOperation):
     def non_raising_func_code(self, builder, r):
@@ -648,6 +649,34 @@
         builder.guard_op = op
         builder.loop.operations.append(op)
 
+# 6. a conditional call (for now always with no exception raised)
+class CondCallOperation(BaseCallOperation):
+    def produce_into(self, builder, r):
+        fail_subset = builder.subset_of_intvars(r)
+        v_cond = builder.get_bool_var(r)
+        subset = builder.subset_of_intvars(r)[:4]
+        for i in range(len(subset)):
+            if r.random() < 0.35:
+                subset[i] = ConstInt(r.random_integer())
+        #
+        seen = []
+        def call_me(*args):
+            if len(seen) == 0:
+                seen.append(args)
+            else:
+                assert seen[0] == args
+        #
+        TP = lltype.FuncType([lltype.Signed] * len(subset), lltype.Void)
+        ptr = llhelper(lltype.Ptr(TP), call_me)
+        c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu)
+        args = [v_cond, c_addr] + subset
+        descr = self.getcalldescr(builder, TP)
+        self.put(builder, args, descr)
+        op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None,
+                          descr=builder.getfaildescr())
+        op.setfailargs(fail_subset)
+        builder.loop.operations.append(op)
+
 # ____________________________________________________________
 
 OPERATIONS = test_random.OPERATIONS[:]
@@ -684,6 +713,7 @@
     OPERATIONS.append(RaisingCallOperationGuardNoException(rop.CALL))
     OPERATIONS.append(RaisingCallOperationWrongGuardException(rop.CALL))
     OPERATIONS.append(CallOperationException(rop.CALL))
+    OPERATIONS.append(CondCallOperation(rop.COND_CALL))
 OPERATIONS.append(GuardNonNullClassOperation(rop.GUARD_NONNULL_CLASS))
 
 LLtypeOperationBuilder.OPERATIONS = OPERATIONS
diff --git a/rpython/jit/backend/x86/assembler.py 
b/rpython/jit/backend/x86/assembler.py
--- a/rpython/jit/backend/x86/assembler.py
+++ b/rpython/jit/backend/x86/assembler.py
@@ -14,7 +14,7 @@
 from rpython.rlib.jit import AsmInfo
 from rpython.jit.backend.model import CompiledLoopToken
 from rpython.jit.backend.x86.regalloc import (RegAlloc, get_ebp_ofs,
-    gpr_reg_mgr_cls, xmm_reg_mgr_cls, _register_arguments)
+    gpr_reg_mgr_cls, xmm_reg_mgr_cls)
 from rpython.jit.backend.llsupport.regalloc import (get_scale, 
valid_addressing_size)
 from rpython.jit.backend.x86.arch import (FRAME_FIXED_SIZE, WORD, IS_X86_64,
                                        JITFRAME_FIXED_SIZE, IS_X86_32,
@@ -154,17 +154,24 @@
         come.
         """
         mc = codebuf.MachineCodeBlockWrapper()
-        self._push_all_regs_to_frame(mc, [], supports_floats, callee_only)
+        # copy registers to the frame, with the exception of the
+        # 'cond_call_register_arguments' and eax, because these have already
+        # been saved by the caller.  Note that this is not symmetrical:
+        # these 5 registers are saved by the caller but restored here at
+        # the end of this function.
+        self._push_all_regs_to_frame(mc, cond_call_register_arguments + [eax],
+                                     supports_floats, callee_only)
         if IS_X86_64:
-            mc.SUB(esp, imm(WORD))
+            mc.SUB(esp, imm(WORD))     # alignment
             self.set_extra_stack_depth(mc, 2 * WORD)
+            # the arguments are already in the correct registers
         else:
-            # we want space for 3 arguments + call + alignment
-            # the caller is responsible for putting arguments in the right spot
+            # we want space for 4 arguments + call + alignment
             mc.SUB(esp, imm(WORD * 7))
             self.set_extra_stack_depth(mc, 8 * WORD)
+            # store the arguments at the correct place in the stack
             for i in range(4):
-                mc.MOV_sr(i * WORD, _register_arguments[i].value)
+                mc.MOV_sr(i * WORD, cond_call_register_arguments[i].value)
         mc.CALL(eax)
         if IS_X86_64:
             mc.ADD(esp, imm(WORD))
@@ -172,8 +179,8 @@
             mc.ADD(esp, imm(WORD * 7))
         self.set_extra_stack_depth(mc, 0)
         self._reload_frame_if_necessary(mc, align_stack=True)
-        self._pop_all_regs_from_frame(mc, [], supports_floats,
-                                      callee_only)
+        self._pop_all_regs_from_frame(mc, [], supports_floats, callee_only)
+        self.pop_gcmap(mc)   # push_gcmap(store=True) done by the caller
         mc.RET()
         return mc.materialize(self.cpu.asmmemmgr, [])
 
@@ -1755,7 +1762,7 @@
             regs = gpr_reg_mgr_cls.save_around_call_regs
         else:
             regs = gpr_reg_mgr_cls.all_regs
-        for i, gpr in enumerate(regs):
+        for gpr in regs:
             if gpr not in ignored_regs:
                 v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
                 mc.MOV_br(v * WORD + base_ofs, gpr.value)
@@ -1777,7 +1784,7 @@
             regs = gpr_reg_mgr_cls.save_around_call_regs
         else:
             regs = gpr_reg_mgr_cls.all_regs
-        for i, gpr in enumerate(regs):
+        for gpr in regs:
             if gpr not in ignored_regs:
                 v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
                 mc.MOV_rb(gpr.value, v * WORD + base_ofs)
@@ -2161,11 +2168,33 @@
     def label(self):
         self._check_frame_depth_debug(self.mc)
 
-    def cond_call(self, op, gcmap, cond_loc, call_loc):
-        self.mc.TEST(cond_loc, cond_loc)
+    def cond_call(self, op, gcmap, loc_cond, imm_func, arglocs):
+        self.mc.TEST(loc_cond, loc_cond)
         self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
         jmp_adr = self.mc.get_relative_pos()
+        #
         self.push_gcmap(self.mc, gcmap, store=True)
+        #
+        # first save away the 4 registers from 'cond_call_register_arguments'
+        # plus the register 'eax'
+        base_ofs = self.cpu.get_baseofs_of_frame_field()
+        should_be_saved = self._regalloc.rm.reg_bindings.values()
+        for gpr in cond_call_register_arguments + [eax]:
+            if gpr not in should_be_saved:
+                continue
+            v = gpr_reg_mgr_cls.all_reg_indexes[gpr.value]
+            self.mc.MOV_br(v * WORD + base_ofs, gpr.value)
+        #
+        # load the 0-to-4 arguments into these registers
+        from rpython.jit.backend.x86.jump import remap_frame_layout
+        remap_frame_layout(self, arglocs,
+                           cond_call_register_arguments[:len(arglocs)],
+                           X86_64_SCRATCH_REG if IS_X86_64 else None)
+        #
+        # load the constant address of the function to call into eax
+        self.mc.MOV(eax, imm_func)
+        #
+        # figure out which variant of cond_call_slowpath to call, and call it
         callee_only = False
         floats = False
         if self._regalloc is not None:
@@ -2178,11 +2207,13 @@
                 floats = True
         cond_call_adr = self.cond_call_slowpath[floats * 2 + callee_only]
         self.mc.CALL(imm(cond_call_adr))
-        self.pop_gcmap(self.mc)
-        # never any result value
+        # restoring the registers saved above, and doing pop_gcmap(), is left
+        # to the cond_call_slowpath helper.  We never have any result value.
         offset = self.mc.get_relative_pos() - jmp_adr
         assert 0 < offset <= 127
         self.mc.overwrite(jmp_adr-1, chr(offset))
+        # XXX if the next operation is a GUARD_NO_EXCEPTION, we should
+        # somehow jump over it too in the fast path
 
     def malloc_cond(self, nursery_free_adr, nursery_top_adr, size, gcmap):
         assert size & (WORD-1) == 0     # must be correctly aligned
@@ -2348,5 +2379,7 @@
     os.write(2, '[x86/asm] %s\n' % msg)
     raise NotImplementedError(msg)
 
+cond_call_register_arguments = [edi, esi, edx, ecx]
+
 class BridgeAlreadyCompiled(Exception):
     pass
diff --git a/rpython/jit/backend/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -119,8 +119,6 @@
 for _i, _reg in enumerate(gpr_reg_mgr_cls.all_regs):
     gpr_reg_mgr_cls.all_reg_indexes[_reg.value] = _i
 
-_register_arguments = [edi, esi, edx, ecx]
-
 
 class RegAlloc(BaseRegalloc):
 
@@ -801,23 +799,26 @@
     consider_cond_call_gc_wb_array = consider_cond_call_gc_wb
 
     def consider_cond_call(self, op):
+        # A 32-bit-only, asmgcc-only issue: 'cond_call_register_arguments'
+        # contains edi and esi, which are also in asmgcroot.py:ASM_FRAMEDATA.
+        # We must make sure that edi and esi do not contain GC pointers.
+        if IS_X86_32 and self.assembler._is_asmgcc():
+            for box, loc in self.rm.reg_bindings.items():
+                if (loc == edi or loc == esi) and box.type == REF:
+                    self.rm.force_spill_var(box)
+                    assert box not in self.rm.reg_bindings
+        #
         assert op.result is None
         args = op.getarglist()
-        assert 2 <= len(args) <= 4 + 2
-        tmpbox = TempBox()
-        self.rm.force_allocate_reg(tmpbox, selected_reg=eax)
+        assert 2 <= len(args) <= 4 + 2     # maximum 4 arguments
+        loc_cond = self.make_sure_var_in_reg(args[0], args)
         v = args[1]
         assert isinstance(v, Const)
-        imm = self.rm.convert_to_imm(v)
-        self.assembler.regalloc_mov(imm, eax)
-        args_so_far = [tmpbox]
-        for i in range(2, len(args)):
-            reg = _register_arguments[i - 2]
-            self.make_sure_var_in_reg(args[i], args_so_far, selected_reg=reg)
-            args_so_far.append(args[i])
-        loc_cond = self.make_sure_var_in_reg(args[0], args)
-        self.assembler.cond_call(op, self.get_gcmap([eax]), loc_cond, eax)
-        self.rm.possibly_free_var(tmpbox)
+        imm_func = self.rm.convert_to_imm(v)
+        arglocs = [self.loc(args[i]) for i in range(2, len(args))]
+        gcmap = self.get_gcmap()
+        self.rm.possibly_free_var(args[0])
+        self.assembler.cond_call(op, gcmap, loc_cond, imm_func, arglocs)
 
     def consider_call_malloc_nursery(self, op):
         size_box = op.getarg(0)
diff --git a/rpython/jit/metainterp/history.py 
b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -34,7 +34,6 @@
             return 'int'     # singlefloats are stored in an int
         if TYPE in (lltype.Float, lltype.SingleFloat):
             raise NotImplementedError("type %s not supported" % TYPE)
-        # XXX fix this for oo...
         if (TYPE != llmemory.Address and
             rffi.sizeof(TYPE) > rffi.sizeof(lltype.Signed)):
             if supports_longlong and TYPE is not lltype.LongFloat:
@@ -168,18 +167,11 @@
     def __init__(self, identifier=None):
         self.identifier = identifier      # for testing
 
+
 class BasicFailDescr(AbstractFailDescr):
     def __init__(self, identifier=None):
         self.identifier = identifier      # for testing
 
-class AbstractMethDescr(AbstractDescr):
-    # the base class of the result of cpu.methdescrof()
-    jitcodes = None
-    def setup(self, jitcodes):
-        # jitcodes maps { runtimeClass -> jitcode for runtimeClass.methname }
-        self.jitcodes = jitcodes
-    def get_jitcode_for_class(self, oocls):
-        return self.jitcodes[oocls]
 
 class Const(AbstractValue):
     __slots__ = ()
diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py 
b/rpython/jit/metainterp/optimizeopt/virtualstate.py
--- a/rpython/jit/metainterp/optimizeopt/virtualstate.py
+++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py
@@ -195,11 +195,10 @@
             raise BadVirtualState
         if not value.is_virtual():
             raise BadVirtualState
+        if len(self.fieldstate) > value.getlength():
+            raise BadVirtualState
         for i in range(len(self.fieldstate)):
-            try:
-                v = value.get_item_value(i)
-            except IndexError:
-                raise BadVirtualState
+            v = value.get_item_value(i)
             s = self.fieldstate[i]
             if s.position > self.position:
                 s.enum_forced_boxes(boxes, v, optimizer)
@@ -269,13 +268,13 @@
             raise BadVirtualState
         if not value.is_virtual():
             raise BadVirtualState
+        if len(self.fielddescrs) > len(value._items):
+            raise BadVirtualState
         p = 0
         for i in range(len(self.fielddescrs)):
             for j in range(len(self.fielddescrs[i])):
                 try:
                     v = value._items[i][self.fielddescrs[i][j]]
-                except IndexError:
-                    raise BadVirtualState
                 except KeyError:
                     raise BadVirtualState
                 s = self.fieldstate[p]
diff --git a/rpython/jit/metainterp/test/test_immutable.py 
b/rpython/jit/metainterp/test/test_immutable.py
--- a/rpython/jit/metainterp/test/test_immutable.py
+++ b/rpython/jit/metainterp/test/test_immutable.py
@@ -69,6 +69,28 @@
         self.check_operations_history(getfield_gc=0, getfield_gc_pure=1,
                             getarrayitem_gc=0, getarrayitem_gc_pure=1)
 
+    def test_array_index_error(self):
+        class X(object):
+            _immutable_fields_ = ["y[*]"]
+
+            def __init__(self, x):
+                self.y = x
+
+            def get(self, index):
+                try:
+                    return self.y[index]
+                except IndexError:
+                    return -41
+
+        def f(index):
+            l = [1, 2, 3, 4]
+            l[2] = 30
+            a = escape(X(l))
+            return a.get(index)
+        res = self.interp_operations(f, [2], listops=True)
+        assert res == 30
+        self.check_operations_history(getfield_gc=0, getfield_gc_pure=1,
+                            getarrayitem_gc=0, getarrayitem_gc_pure=1)
 
     def test_array_in_immutable(self):
         class X(object):
diff --git a/rpython/jit/tl/targettlc.py b/rpython/jit/tl/targettlc.py
--- a/rpython/jit/tl/targettlc.py
+++ b/rpython/jit/tl/targettlc.py
@@ -2,7 +2,6 @@
 import py
 py.path.local(__file__)
 from rpython.jit.tl.tlc import interp, interp_nonjit, ConstantPool
-from rpython.jit.codewriter.policy import JitPolicy
 from rpython.jit.backend.hlinfo import highleveljitinfo
 
 
@@ -54,14 +53,10 @@
     return decode_program(f.readall())
 
 def target(driver, args):
-    return entry_point, None
+    return entry_point
 
 # ____________________________________________________________
 
-def jitpolicy(driver):
-    """Returns the JIT policy to use when translating."""
-    return JitPolicy()
-
 if __name__ == '__main__':
     import sys
     sys.exit(entry_point(sys.argv))
diff --git a/rpython/jit/tl/targettlr.py b/rpython/jit/tl/targettlr.py
--- a/rpython/jit/tl/targettlr.py
+++ b/rpython/jit/tl/targettlr.py
@@ -29,15 +29,10 @@
     return bytecode
 
 def target(driver, args):
-    return entry_point, None
+    return entry_point
 
 # ____________________________________________________________
 
-from rpython.jit.codewriter.policy import JitPolicy
-
-def jitpolicy(driver):
-    return JitPolicy()
-
 if __name__ == '__main__':
     import sys
     sys.exit(entry_point(sys.argv))
diff --git a/rpython/jit/tl/tla/targettla.py b/rpython/jit/tl/tla/targettla.py
--- a/rpython/jit/tl/tla/targettla.py
+++ b/rpython/jit/tl/tla/targettla.py
@@ -28,9 +28,6 @@
 def target(driver, args):
     return entry_point, None
 
-def jitpolicy(driver):
-    from rpython.jit.codewriter.policy import JitPolicy
-    return JitPolicy()
 # ____________________________________________________________
 
 
diff --git a/rpython/memory/gctransform/asmgcroot.py 
b/rpython/memory/gctransform/asmgcroot.py
--- a/rpython/memory/gctransform/asmgcroot.py
+++ b/rpython/memory/gctransform/asmgcroot.py
@@ -729,6 +729,10 @@
 #   - frame address (actually the addr of the retaddr of the current function;
 #                    that's the last word of the frame in memory)
 #
+# On 64 bits, it is an array of 7 values instead of 5:
+#
+#   - %rbx, %r12, %r13, %r14, %r15, %rbp; and the frame address
+#
 
 if IS_64_BITS:
     CALLEE_SAVED_REGS = 6
diff --git a/rpython/rlib/longlong2float.py b/rpython/rlib/longlong2float.py
--- a/rpython/rlib/longlong2float.py
+++ b/rpython/rlib/longlong2float.py
@@ -68,14 +68,12 @@
 uint2singlefloat = rffi.llexternal(
     "pypy__uint2singlefloat", [rffi.UINT], rffi.FLOAT,
     _callable=uint2singlefloat_emulator, compilation_info=eci,
-    _nowrapper=True, elidable_function=True, sandboxsafe=True,
-    oo_primitive="pypy__uint2singlefloat")
+    _nowrapper=True, elidable_function=True, sandboxsafe=True)
 
 singlefloat2uint = rffi.llexternal(
     "pypy__singlefloat2uint", [rffi.FLOAT], rffi.UINT,
     _callable=singlefloat2uint_emulator, compilation_info=eci,
-    _nowrapper=True, elidable_function=True, sandboxsafe=True,
-    oo_primitive="pypy__singlefloat2uint")
+    _nowrapper=True, elidable_function=True, sandboxsafe=True)
 
 
 class Float2LongLongEntry(ExtRegistryEntry):
diff --git a/rpython/rlib/rlocale.py b/rpython/rlib/rlocale.py
--- a/rpython/rlib/rlocale.py
+++ b/rpython/rlib/rlocale.py
@@ -193,11 +193,11 @@
         raise LocaleError("unsupported locale setting")
     return rffi.charp2str(ll_result)
 
-isalpha = external('isalpha', [rffi.INT], rffi.INT, 
oo_primitive='locale_isalpha')
-isupper = external('isupper', [rffi.INT], rffi.INT, 
oo_primitive='locale_isupper')
-islower = external('islower', [rffi.INT], rffi.INT, 
oo_primitive='locale_islower')
-tolower = external('tolower', [rffi.INT], rffi.INT, 
oo_primitive='locale_tolower')
-isalnum = external('isalnum', [rffi.INT], rffi.INT, 
oo_primitive='locale_isalnum')
+isalpha = external('isalpha', [rffi.INT], rffi.INT)
+isupper = external('isupper', [rffi.INT], rffi.INT)
+islower = external('islower', [rffi.INT], rffi.INT)
+tolower = external('tolower', [rffi.INT], rffi.INT)
+isalnum = external('isalnum', [rffi.INT], rffi.INT)
 
 if HAVE_LANGINFO:
     _nl_langinfo = external('nl_langinfo', [rffi.INT], rffi.CCHARP)
diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py
--- a/rpython/rlib/streamio.py
+++ b/rpython/rlib/streamio.py
@@ -185,11 +185,8 @@
     SetEndOfFile = rffi.llexternal('SetEndOfFile', [HANDLE], BOOL,
                                    compilation_info=_eci)
 
-    # HACK: These implementations are specific to MSVCRT and the C backend.
-    # When generating on CLI or JVM, these are patched out.
-    # See PyPyTarget.target() in targetpypystandalone.py
     def _setfd_binary(fd):
-        #Allow this to succeed on invalid fd's
+        # Allow this to succeed on invalid fd's
         if rposix.is_valid_fd(fd):
             _setmode(fd, os.O_BINARY)
 
diff --git a/rpython/rtyper/lltypesystem/rffi.py 
b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -62,8 +62,8 @@
                compilation_info=ExternalCompilationInfo(),
                sandboxsafe=False, threadsafe='auto',
                _nowrapper=False, calling_conv='c',
-               oo_primitive=None, elidable_function=False,
-               macro=None, random_effects_on_gcobjs='auto'):
+               elidable_function=False, macro=None,
+               random_effects_on_gcobjs='auto'):
     """Build an external function that will invoke the C function 'name'
     with the given 'args' types and 'result' type.
 
@@ -97,8 +97,6 @@
     if elidable_function:
         _callable._elidable_function_ = True
     kwds = {}
-    if oo_primitive:
-        kwds['oo_primitive'] = oo_primitive
 
     has_callback = False
     for ARG in args:
@@ -651,6 +649,10 @@
 # char *
 CCHARP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True}))
 
+# const char *
+CONST_CCHARP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True,
+                                       'render_as_const': True}))
+
 # wchar_t *
 CWCHARP = lltype.Ptr(lltype.Array(lltype.UniChar, hints={'nolength': True}))
 
diff --git a/rpython/rtyper/rlist.py b/rpython/rtyper/rlist.py
--- a/rpython/rtyper/rlist.py
+++ b/rpython/rtyper/rlist.py
@@ -247,27 +247,22 @@
         v_lst, v_index = hop.inputargs(r_lst, Signed)
         if checkidx:
             hop.exception_is_here()
+            spec = dum_checkidx
         else:
+            spec = dum_nocheck
             hop.exception_cannot_occur()
-        if hop.args_s[0].listdef.listitem.mutated or checkidx:
-            if hop.args_s[1].nonneg:
-                llfn = ll_getitem_nonneg
-            else:
-                llfn = ll_getitem
-            if checkidx:
-                spec = dum_checkidx
-            else:
-                spec = dum_nocheck
-            c_func_marker = hop.inputconst(Void, spec)
-            v_res = hop.gendirectcall(llfn, c_func_marker, v_lst, v_index)
+        if hop.args_s[0].listdef.listitem.mutated:
+            basegetitem = ll_getitem_fast
         else:
-            # this is the 'foldable' version, which is not used when
-            # we check for IndexError
-            if hop.args_s[1].nonneg:
-                llfn = ll_getitem_foldable_nonneg
-            else:
-                llfn = ll_getitem_foldable
-            v_res = hop.gendirectcall(llfn, v_lst, v_index)
+            basegetitem = ll_getitem_foldable_nonneg
+
+        if hop.args_s[1].nonneg:
+            llfn = ll_getitem_nonneg
+        else:
+            llfn = ll_getitem
+        c_func_marker = hop.inputconst(Void, spec)
+        c_basegetitem = hop.inputconst(Void, basegetitem)
+        v_res = hop.gendirectcall(llfn, c_func_marker, c_basegetitem, v_lst, 
v_index)
         return r_lst.recast(hop.llops, v_res)
 
     rtype_getitem_key = rtype_getitem
@@ -654,16 +649,16 @@
         i += 1
         length_1_i -= 1
 
-def ll_getitem_nonneg(func, l, index):
+def ll_getitem_nonneg(func, basegetitem, l, index):
     ll_assert(index >= 0, "unexpectedly negative list getitem index")
     if func is dum_checkidx:
         if index >= l.ll_length():
             raise IndexError
-    return l.ll_getitem_fast(index)
+    return basegetitem(l, index)
 ll_getitem_nonneg._always_inline_ = True
 # no oopspec -- the function is inlined by the JIT
 
-def ll_getitem(func, l, index):
+def ll_getitem(func, basegetitem, l, index):
     if func is dum_checkidx:
         length = l.ll_length()    # common case: 0 <= index < length
         if r_uint(index) >= r_uint(length):
@@ -680,21 +675,18 @@
         if index < 0:
             index += l.ll_length()
             ll_assert(index >= 0, "negative list getitem index out of bound")
+    return basegetitem(l, index)
+# no oopspec -- the function is inlined by the JIT
+
+def ll_getitem_fast(l, index):
     return l.ll_getitem_fast(index)
-# no oopspec -- the function is inlined by the JIT
+ll_getitem_fast._always_inline_ = True
 
 def ll_getitem_foldable_nonneg(l, index):
     ll_assert(index >= 0, "unexpectedly negative list getitem index")
     return l.ll_getitem_fast(index)
 ll_getitem_foldable_nonneg.oopspec = 'list.getitem_foldable(l, index)'
 
-def ll_getitem_foldable(l, index):
-    if index < 0:
-        index += l.ll_length()
-    return ll_getitem_foldable_nonneg(l, index)
-ll_getitem_foldable._always_inline_ = True
-# no oopspec -- the function is inlined by the JIT
-
 def ll_setitem_nonneg(func, l, index, newitem):
     ll_assert(index >= 0, "unexpectedly negative list setitem index")
     if func is dum_checkidx:
diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py
--- a/rpython/rtyper/rtyper.py
+++ b/rpython/rtyper/rtyper.py
@@ -58,7 +58,6 @@
         self.classdef_to_pytypeobject = {}
         self.concrete_calltables = {}
         self.class_pbc_attributes = {}
-        self.oo_meth_impls = {}
         self.cache_dummy_values = {}
         self.lltype2vtable = {}
         self.typererrors = []
diff --git a/rpython/rtyper/test/test_rlist.py 
b/rpython/rtyper/test/test_rlist.py
--- a/rpython/rtyper/test/test_rlist.py
+++ b/rpython/rtyper/test/test_rlist.py
@@ -14,15 +14,19 @@
 from rpython.translator.translator import TranslationContext
 
 
-# undo the specialization parameter
+# undo the specialization parameters
 for n1 in 'get set del'.split():
+    if n1 == "get":
+        extraarg = "ll_getitem_fast, "
+    else:
+        extraarg = ""
     for n2 in '', '_nonneg':
         name = 'll_%sitem%s' % (n1, n2)
         globals()['_' + name] = globals()[name]
         exec """if 1:
             def %s(*args):
-                return _%s(dum_checkidx, *args)
-""" % (name, name)
+                return _%s(dum_checkidx, %s*args)
+""" % (name, name, extraarg)
 del n1, n2, name
 
 
@@ -1400,7 +1404,7 @@
             block = graph.startblock
             op = block.operations[-1]
             assert op.opname == 'direct_call'
-            func = op.args[0].value._obj._callable
+            func = op.args[2].value
             assert ('foldable' in func.func_name) == \
                    ("y[*]" in immutable_fields)
 
@@ -1511,8 +1515,8 @@
         block = graph.startblock
         lst1_getitem_op = block.operations[-3]     # XXX graph fishing
         lst2_getitem_op = block.operations[-2]
-        func1 = lst1_getitem_op.args[0].value._obj._callable
-        func2 = lst2_getitem_op.args[0].value._obj._callable
+        func1 = lst1_getitem_op.args[2].value
+        func2 = lst2_getitem_op.args[2].value
         assert func1.oopspec == 'list.getitem_foldable(l, index)'
         assert not hasattr(func2, 'oopspec')
 
diff --git a/rpython/translator/backendopt/test/test_removenoops.py 
b/rpython/translator/backendopt/test/test_removenoops.py
--- a/rpython/translator/backendopt/test/test_removenoops.py
+++ b/rpython/translator/backendopt/test/test_removenoops.py
@@ -97,9 +97,8 @@
 
 
 def test_remove_unaryops():
-    # We really want to use remove_unaryops for things like ooupcast and
-    # oodowncast in dynamically typed languages, but it's easier to test
-    # it with operations on ints here.
+    # We really want to use remove_unaryops for more complex operations, but
+    # it's easier to test it with operations on ints here.
     def f(x):
         i = llop.int_invert(lltype.Signed, x)
         i = llop.int_add(lltype.Signed, x, 1)
diff --git a/rpython/translator/c/node.py b/rpython/translator/c/node.py
--- a/rpython/translator/c/node.py
+++ b/rpython/translator/c/node.py
@@ -358,6 +358,8 @@
             self.fullptrtypename = 'void *@'
         else:
             self.fullptrtypename = self.itemtypename.replace('@', '*@')
+            if ARRAY._hints.get("render_as_const"):
+                self.fullptrtypename = 'const ' + self.fullptrtypename
 
     def setup(self):
         """Array loops are forbidden by ForwardReference.become() because
diff --git a/rpython/translator/c/test/test_lltyped.py 
b/rpython/translator/c/test/test_lltyped.py
--- a/rpython/translator/c/test/test_lltyped.py
+++ b/rpython/translator/c/test/test_lltyped.py
@@ -1,5 +1,6 @@
 import py
 from rpython.rtyper.lltypesystem.lltype import *
+from rpython.rtyper.lltypesystem import rffi
 from rpython.translator.c.test.test_genc import compile
 from rpython.tool.sourcetools import func_with_new_name
 
@@ -314,14 +315,14 @@
         from rpython.rtyper.lltypesystem.rstr import STR
         from rpython.rtyper.lltypesystem import rffi, llmemory, lltype
         P = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))
-        
+
         def f():
             a = llstr("xyz")
             b = (llmemory.cast_ptr_to_adr(a) + llmemory.offsetof(STR, 'chars')
                  + llmemory.itemoffsetof(STR.chars, 0))
             buf = rffi.cast(rffi.VOIDP, b)
             return buf[2]
-        
+
         fn = self.getcompiled(f, [])
         res = fn()
         assert res == 'z'
@@ -941,3 +942,21 @@
         assert fn(0) == 10
         assert fn(1) == 10 + 521
         assert fn(2) == 10 + 34
+
+    def test_const_char_star(self):
+        from rpython.translator.tool.cbuild import ExternalCompilationInfo
+
+        eci = ExternalCompilationInfo(includes=["stdlib.h"])
+        atoi = rffi.llexternal('atoi', [rffi.CONST_CCHARP], rffi.INT,
+                               compilation_info=eci)
+
+        def f(n):
+            s = malloc(rffi.CCHARP.TO, 2, flavor='raw')
+            s[0] = '9'
+            s[1] = '\0'
+            res = atoi(rffi.cast(rffi.CONST_CCHARP, s))
+            free(s, flavor='raw')
+            return res
+
+        fn = self.getcompiled(f, [int])
+        assert fn(0) == 9
diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py
--- a/rpython/translator/driver.py
+++ b/rpython/translator/driver.py
@@ -354,8 +354,12 @@
         """ Generate bytecodes for JIT and flow the JIT helper functions
         lltype version
         """
-        get_policy = self.extra['jitpolicy']
-        self.jitpolicy = get_policy(self)
+        from rpython.jit.codewriter.policy import JitPolicy
+        get_policy = self.extra.get('jitpolicy', None)
+        if get_policy is None:
+            self.jitpolicy = JitPolicy()
+        else:
+            self.jitpolicy = get_policy(self)
         #
         from rpython.jit.metainterp.warmspot import apply_jit
         apply_jit(self.translator, policy=self.jitpolicy,
@@ -544,9 +548,14 @@
 
         try:
             entry_point, inputtypes, policy = spec
+        except TypeError:
+            # not a tuple at all
+            entry_point = spec
+            inputtypes = policy = None
         except ValueError:
+            policy = None
             entry_point, inputtypes = spec
-            policy = None
+
 
         driver.setup(entry_point, inputtypes,
                      policy=policy,
diff --git a/rpython/translator/goal/targetjitstandalone.py 
b/rpython/translator/goal/targetjitstandalone.py
--- a/rpython/translator/goal/targetjitstandalone.py
+++ b/rpython/translator/goal/targetjitstandalone.py
@@ -3,7 +3,6 @@
 """
 
 from rpython.rlib import jit
-from rpython.jit.codewriter.policy import JitPolicy
 
 driver = jit.JitDriver(greens = [], reds = 'auto')
 driver2 = jit.JitDriver(greens = [], reds = 'auto')
@@ -28,7 +27,9 @@
 
 def entry_point(argv):
     if len(argv) < 3:
-        print "Usage: jitstandalone <number> <another number>"
+        print "Usage: jitstandalone <count1> <count2>"
+        print "runs a total of '2 * count1 * count2' iterations"
+        return 0
     count1 = int(argv[1])
     count2 = int(argv[2])
     s = 0
@@ -38,7 +39,4 @@
     return 0
 
 def target(*args):
-    return entry_point, None
-
-def jitpolicy(driver):
-    return JitPolicy()
+    return entry_point
diff --git a/rpython/translator/goal/targetnopstandalone.py 
b/rpython/translator/goal/targetnopstandalone.py
--- a/rpython/translator/goal/targetnopstandalone.py
+++ b/rpython/translator/goal/targetnopstandalone.py
@@ -19,4 +19,4 @@
 # _____ Define and setup target ___
 
 def target(*args):
-    return entry_point, None
+    return entry_point
diff --git a/rpython/translator/goal/targetrpystonedalone.py 
b/rpython/translator/goal/targetrpystonedalone.py
--- a/rpython/translator/goal/targetrpystonedalone.py
+++ b/rpython/translator/goal/targetrpystonedalone.py
@@ -60,13 +60,12 @@
 # _____ Define and setup target ___
 
 def target(*args):
-    return entry_point, None
+    return entry_point
 
 """
 Why is this a stand-alone target?
 
-The above target specifies None as the argument types list.
-This is a case treated specially in the driver.py . If the list
-of input types is empty, it is meant to be a list of strings,
-actually implementing argv of the executable.
+The above target specifies no argument types list.
+This is a case treated specially in the driver.py . The only argument is meant
+to be a list of strings, actually implementing argv of the executable.
 """
diff --git a/rpython/translator/goal/translate.py 
b/rpython/translator/goal/translate.py
--- a/rpython/translator/goal/translate.py
+++ b/rpython/translator/goal/translate.py
@@ -284,8 +284,6 @@
                                                        default_goal='compile')
         log_config(translateconfig, "translate.py configuration")
         if config.translation.jit:
-            if 'jitpolicy' not in targetspec_dic:
-                raise Exception('target has no jitpolicy defined.')
             if (translateconfig.goals != ['annotate'] and
                 translateconfig.goals != ['rtype']):
                 drv.set_extra_goals(['pyjitpl'])
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to