Author: Philip Jenvey <pjen...@underboss.org>
Branch: py3k
Changeset: r65911:de2ab686aa9d
Date: 2013-08-02 12:03 -0700
http://bitbucket.org/pypy/pypy/changeset/de2ab686aa9d/

Log:    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/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py
--- a/lib_pypy/_sqlite3.py
+++ b/lib_pypy/_sqlite3.py
@@ -1317,7 +1317,7 @@
         for i in xrange(_lib.sqlite3_column_count(self._statement)):
             name = _lib.sqlite3_column_name(self._statement, i)
             if name:
-                name = _ffi.string(name).decode('utf-8').split("[")[0].strip()
+                name = _ffi.string(name).split("[")[0].strip()
             desc.append((name, None, None, None, None, None, None))
         return desc
 
diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py
--- a/pypy/doc/conf.py
+++ b/pypy/doc/conf.py
@@ -45,9 +45,9 @@
 # built documents.
 #
 # The short X.Y version.
-version = '2.0'
+version = '2.1'
 # The full version, including alpha/beta/rc tags.
-release = '2.0.2'
+release = '2.1.0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/pypy/doc/getting-started-python.rst 
b/pypy/doc/getting-started-python.rst
--- a/pypy/doc/getting-started-python.rst
+++ b/pypy/doc/getting-started-python.rst
@@ -104,8 +104,8 @@
 executable. The executable behaves mostly like a normal Python interpreter::
 
     $ ./pypy-c
-    Python 2.7.3 (7e4f0faa3d51, Nov 22 2012, 10:35:18)
-    [PyPy 2.0.0 with GCC 4.7.1] on linux2
+    Python 2.7.3 (480845e6b1dd, Jul 31 2013, 11:05:31)
+    [PyPy 2.1.0 with GCC 4.7.1] on linux2
     Type "help", "copyright", "credits" or "license" for more information.
     And now for something completely different: ``RPython magically makes you 
rich
     and famous (says so on the tin)''
@@ -171,7 +171,7 @@
 the ``bin/pypy`` executable.
 
 To install PyPy system wide on unix-like systems, it is recommended to put the
-whole hierarchy alone (e.g. in ``/opt/pypy2.0``) and put a symlink to the
+whole hierarchy alone (e.g. in ``/opt/pypy2.1``) and put a symlink to the
 ``pypy`` executable into ``/usr/bin`` or ``/usr/local/bin``
 
 If the executable fails to find suitable libraries, it will report
diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst
--- a/pypy/doc/getting-started.rst
+++ b/pypy/doc/getting-started.rst
@@ -53,10 +53,10 @@
 PyPy is ready to be executed as soon as you unpack the tarball or the zip
 file, with no need to install it in any specific location::
 
-    $ tar xf pypy-2.0.tar.bz2
-    $ ./pypy-2.0/bin/pypy
-    Python 2.7.3 (7e4f0faa3d51, Nov 22 2012, 10:35:18)
-    [PyPy 2.0.0 with GCC 4.7.1] on linux2
+    $ tar xf pypy-2.1.tar.bz2
+    $ ./pypy-2.1/bin/pypy
+    Python 2.7.3 (480845e6b1dd, Jul 31 2013, 11:05:31)
+    [PyPy 2.1.0 with GCC 4.4.3] on linux2
     Type "help", "copyright", "credits" or "license" for more information.
     And now for something completely different: ``PyPy is an exciting 
technology
     that lets you to write fast, portable, multi-platform interpreters with 
less
@@ -75,14 +75,14 @@
 
     $ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py
 
-    $ ./pypy-2.0/bin/pypy distribute_setup.py
+    $ ./pypy-2.1/bin/pypy distribute_setup.py
 
-    $ ./pypy-2.0/bin/pypy get-pip.py
+    $ ./pypy-2.1/bin/pypy get-pip.py
 
-    $ ./pypy-2.0/bin/pip install pygments  # for example
+    $ ./pypy-2.1/bin/pip install pygments  # for example
 
-3rd party libraries will be installed in ``pypy-2.0/site-packages``, and
-the scripts in ``pypy-2.0/bin``.
+3rd party libraries will be installed in ``pypy-2.1/site-packages``, and
+the scripts in ``pypy-2.1/bin``.
 
 Installing using virtualenv
 ---------------------------
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -40,7 +40,7 @@
 
 * `FAQ`_: some frequently asked questions.
 
-* `Release 2.0.2`_: the latest official release
+* `Release 2.1.0`_: the latest official release
 
 * `PyPy Blog`_: news and status info about PyPy 
 
@@ -110,7 +110,7 @@
 .. _`Getting Started`: getting-started.html
 .. _`Papers`: extradoc.html
 .. _`Videos`: video-index.html
-.. _`Release 2.0.2`: http://pypy.org/download.html
+.. _`Release 2.1.0`: http://pypy.org/download.html
 .. _`speed.pypy.org`: http://speed.pypy.org
 .. _`RPython toolchain`: translation.html
 .. _`potential project ideas`: project-ideas.html
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, targeting 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,13 @@
 .. 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.
+
+.. branch: mro-reorder-numpypy-str
+No longer delegate numpy string_ methods to space.StringObject, in numpy
+this works by kind of by accident. Support for merging the refactor-str-types
+branch
diff --git a/pypy/module/cpyext/include/patchlevel.h 
b/pypy/module/cpyext/include/patchlevel.h
--- a/pypy/module/cpyext/include/patchlevel.h
+++ b/pypy/module/cpyext/include/patchlevel.h
@@ -29,7 +29,7 @@
 #define PY_VERSION             "3.2.3"
 
 /* PyPy version as a string */
-#define PYPY_VERSION "2.1.0-alpha0"
+#define PYPY_VERSION "2.2.0-alpha0"
 
 /* Subversion Revision number of this file (not of the repository).
  * Empty since Mercurial migration. */
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
@@ -852,15 +852,10 @@
 # Depending on which opcodes are enabled, eg. CALL_METHOD we bump the version
 # number by some constant
 #
-#  * 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)
@@ -378,12 +379,14 @@
         return self
 
 class W_CharacterBox(W_FlexibleBox):
-    pass
+    def convert_to(self, dtype):
+        # XXX assert dtype is str type
+        return self
+
 
 class W_StringBox(W_CharacterBox):
     def descr__new__string_box(space, w_subtype, w_arg):
         from pypy.module.micronumpy.interp_dtype import new_string_dtype
-
         arg = space.str_w(space.str(w_arg))
         arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg)))
         for i in range(len(arg)):
@@ -517,6 +520,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),
 )
 
@@ -682,12 +686,12 @@
     __module__ = "numpypy",
 )
 
-W_StringBox.typedef = TypeDef("string_", (str_typedef, W_CharacterBox.typedef),
+W_StringBox.typedef = TypeDef("string_", (W_CharacterBox.typedef, str_typedef),
     __module__ = "numpypy",
     __new__ = interp2app(W_StringBox.descr__new__string_box.im_func),
 )
 
-W_UnicodeBox.typedef = TypeDef("unicode_", (unicode_typedef, 
W_CharacterBox.typedef),
+W_UnicodeBox.typedef = TypeDef("unicode_", (W_CharacterBox.typedef, 
unicode_typedef),
     __module__ = "numpypy",
     __new__ = interp2app(W_UnicodeBox.descr__new__unicode_box.im_func),
 )
diff --git a/pypy/module/micronumpy/interp_dtype.py 
b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -234,6 +234,9 @@
     def is_record_type(self):
         return self.fields is not None
 
+    def is_str_type(self):
+        return self.num == 18
+
     def is_str_or_unicode(self):
         return (self.num == 18 or self.num == 19)
 
diff --git a/pypy/module/micronumpy/interp_ufuncs.py 
b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -328,14 +328,19 @@
             w_out = None
         w_lhs = convert_to_array(space, w_lhs)
         w_rhs = convert_to_array(space, w_rhs)
-        if (w_lhs.get_dtype().is_flexible_type() or \
-                w_rhs.get_dtype().is_flexible_type()):
+        w_ldtype = w_lhs.get_dtype()
+        w_rdtype = w_rhs.get_dtype()
+        if w_ldtype.is_str_type() and w_rdtype.is_str_type() and \
+           self.comparison_func:
+            pass
+        elif (w_ldtype.is_flexible_type() or \
+                w_rdtype.is_flexible_type()):
             raise OperationError(space.w_TypeError, space.wrap(
                  'unsupported operand dtypes %s and %s for "%s"' % \
-                 (w_rhs.get_dtype().get_name(), w_lhs.get_dtype().get_name(),
+                 (w_rdtype.get_name(), w_ldtype.get_name(),
                   self.name)))
         calc_dtype = find_binop_result_dtype(space,
-            w_lhs.get_dtype(), w_rhs.get_dtype(),
+            w_ldtype, w_rdtype,
             int_only=self.int_only,
             promote_to_float=self.promote_to_float,
             promote_bools=self.promote_bools,
diff --git a/pypy/module/micronumpy/stdobjspace.py 
b/pypy/module/micronumpy/stdobjspace.py
deleted file mode 100644
--- a/pypy/module/micronumpy/stdobjspace.py
+++ /dev/null
@@ -1,11 +0,0 @@
-
-from pypy.objspace.std import stringobject
-from pypy.module.micronumpy import interp_boxes
-
-def delegate_stringbox2stringobj(space, w_box):
-    return space.wrap(w_box.dtype.itemtype.to_str(w_box))
-
-def register_delegates(typeorder):
-    typeorder[interp_boxes.W_StringBox] = [
-        (stringobject.W_StringObject, delegate_stringbox2stringobj),
-    ]
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_dtypes.py 
b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -739,6 +739,7 @@
 
 class AppTestStrUnicodeDtypes(BaseNumpyAppTest):
     def test_str_unicode(self):
+        skip('numpypy differs from numpy')
         from numpypy import str_, unicode_, character, flexible, generic
 
         assert str_.mro() == [str_, str, character, flexible, generic, object]
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
@@ -2754,6 +2756,19 @@
         assert a[2] == 'ab'
         raises(TypeError, a, 'sum')
         raises(TypeError, 'a+a')
+        b = array(['abcdefg', 'ab', 'cd'])
+        assert a[2] == b[1]
+        assert bool(a[1])
+        c = array(['ab','cdefg','hi','jk'])
+        # not implemented yet
+        #c[0] += c[3]
+        #assert c[0] == 'abjk'
+
+    def test_to_str(self):
+        from numpypy import array
+        a = array(['abc','abc', 'def', 'ab'], 'S3')
+        b = array(['mnopqr','abcdef', 'ab', 'cd'])
+        assert b[1] != a[1]
 
     def test_string_scalar(self):
         from numpypy import array
@@ -2765,8 +2780,7 @@
         assert str(a.dtype) == '|S1'
         a = array('x', dtype='c')
         assert str(a.dtype) == '|S1'
-        # XXX can sort flexible types, why not comparison?
-        #assert a == 'x'
+        assert a == 'x'
 
     def test_flexible_repr(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/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -1689,6 +1689,22 @@
     def get_size(self):
         return self.size
 
+def str_unary_op(func):
+    specialize.argtype(1)(func)
+    @functools.wraps(func)
+    def dispatcher(self, v1):
+        return func(self, self.to_str(v1))
+    return dispatcher
+
+def str_binary_op(func):
+    specialize.argtype(1, 2)(func)
+    @functools.wraps(func)
+    def dispatcher(self, v1, v2):
+        return func(self,
+            self.to_str(v1),
+            self.to_str(v2)
+        )
+    return dispatcher
 
 class StringType(BaseType, BaseStringType):
     T = lltype.Char
@@ -1696,6 +1712,8 @@
     @jit.unroll_safe
     def coerce(self, space, dtype, w_item):
         from pypy.module.micronumpy.interp_dtype import new_string_dtype
+        if isinstance(w_item, interp_boxes.W_StringBox):
+            return w_item
         arg = space.str_w(space.str(w_item))
         arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg)))
         for i in range(len(arg)):
@@ -1705,6 +1723,7 @@
     @jit.unroll_safe
     def store(self, arr, i, offset, box):
         assert isinstance(box, interp_boxes.W_StringBox)
+        # XXX simplify to range(box.dtype.get_size()) ?
         for k in range(min(self.size, box.arr.size-offset)):
             arr.storage[k + i] = box.arr.storage[k + offset]
 
@@ -1718,7 +1737,7 @@
         builder = StringBuilder()
         assert isinstance(item, interp_boxes.W_StringBox)
         i = item.ofs
-        end = i+self.size
+        end = i + item.dtype.get_size()
         while i < end:
             assert isinstance(item.arr.storage[i], str)
             if item.arr.storage[i] == '\x00':
@@ -1734,10 +1753,53 @@
         builder.append("'")
         return builder.build()
 
-    # XXX move to base class when UnicodeType is supported
+    # XXX move the rest of this to base class when UnicodeType is supported
     def to_builtin_type(self, space, box):
         return space.wrap(self.to_str(box))
 
+    @str_binary_op
+    def eq(self, v1, v2):
+        return v1 == v2
+
+    @str_binary_op
+    def ne(self, v1, v2):
+        return v1 != v2
+
+    @str_binary_op
+    def lt(self, v1, v2):
+        return v1 < v2
+
+    @str_binary_op
+    def le(self, v1, v2):
+        return v1 <= v2
+
+    @str_binary_op
+    def gt(self, v1, v2):
+        return v1 > v2
+
+    @str_binary_op
+    def ge(self, v1, v2):
+        return v1 >= v2
+
+    @str_binary_op
+    def logical_and(self, v1, v2):
+        return bool(v1) and bool(v2)
+
+    @str_binary_op
+    def logical_or(self, v1, v2):
+        return bool(v1) or bool(v2)
+
+    @str_unary_op
+    def logical_not(self, v):
+        return not bool(v)
+
+    @str_binary_op
+    def logical_xor(self, v1, v2):
+        return bool(v1) ^ bool(v2)
+
+    def bool(self, v):
+        return bool(self.to_str(v))
+
     def build_and_convert(self, space, mydtype, box):
         assert isinstance(box, interp_boxes.W_GenericBox)
         if box.get_dtype(space).is_str_or_unicode():
@@ -1753,6 +1815,13 @@
             arr.storage[j] = '\x00'
         return interp_boxes.W_StringBox(arr,  0, arr.dtype)
 
+NonNativeStringType = StringType
+
+class UnicodeType(BaseType, BaseStringType):
+    T = lltype.UniChar
+
+NonNativeUnicodeType = UnicodeType
+
 class VoidType(BaseType, BaseStringType):
     T = lltype.Char
 
@@ -1798,12 +1867,6 @@
         return W_NDimArray(implementation)
 
 NonNativeVoidType = VoidType
-NonNativeStringType = StringType
-
-class UnicodeType(BaseType, BaseStringType):
-    T = lltype.UniChar
-
-NonNativeUnicodeType = UnicodeType
 
 class RecordType(BaseType):
 
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/sys/version.py b/pypy/module/sys/version.py
--- a/pypy/module/sys/version.py
+++ b/pypy/module/sys/version.py
@@ -11,7 +11,7 @@
 #XXX # sync CPYTHON_VERSION with patchlevel.h, package.py
 CPYTHON_API_VERSION        = 1013   #XXX # sync with include/modsupport.h
 
-PYPY_VERSION               = (2, 1, 0, "alpha", 0)    #XXX # sync patchlevel.h
+PYPY_VERSION               = (2, 2, 0, "alpha", 0)    #XXX # sync patchlevel.h
 
 if platform.name == 'msvc':
     COMPILER_INFO = 'MSC v.%d 32 bit' % (platform.version * 10 + 600)
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/module/test_lib_pypy/test_sqlite3.py 
b/pypy/module/test_lib_pypy/test_sqlite3.py
--- a/pypy/module/test_lib_pypy/test_sqlite3.py
+++ b/pypy/module/test_lib_pypy/test_sqlite3.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 """Tests for _sqlite3.py"""
 
 import pytest, sys
@@ -222,3 +223,8 @@
     cur.execute("create table test(a)")
     cur.executemany("insert into test values (?)", [[1], [2], [3]])
     assert cur.lastrowid is None
+
+def test_issue1573(con):
+    cur = con.cursor()
+    cur.execute(u'SELECT 1 as m&#233;il')
+    assert cur.description[0][0] == u"m&#233;il".encode('utf-8')
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
@@ -678,11 +678,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
 
@@ -870,7 +872,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
 
@@ -953,6 +955,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/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -132,10 +132,6 @@
         # when trying to dispatch multimethods.
         # XXX build these lists a bit more automatically later
 
-        if config.objspace.usemodules.micronumpy:
-            from pypy.module.micronumpy.stdobjspace import register_delegates
-            register_delegates(self.typeorder)
-
         self.typeorder[boolobject.W_BoolObject] += [
             #(intobject.W_IntObject,     boolobject.delegate_Bool2IntObject),
             (floatobject.W_FloatObject, floatobject.delegate_Bool2Float),
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/x86/regalloc.py 
b/rpython/jit/backend/x86/regalloc.py
--- a/rpython/jit/backend/x86/regalloc.py
+++ b/rpython/jit/backend/x86/regalloc.py
@@ -799,6 +799,15 @@
     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     # maximum 4 arguments
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/rtyper/test/test_runicode.py 
b/rpython/rtyper/test/test_runicode.py
--- a/rpython/rtyper/test/test_runicode.py
+++ b/rpython/rtyper/test/test_runicode.py
@@ -8,7 +8,7 @@
 
 # ====> test_rstr.py
 
-class BaseTestRUnicode(AbstractTestRstr, BaseRtypingTest):
+class TestRUnicode(AbstractTestRstr, BaseRtypingTest):
     const = unicode
     constchar = unichr
 
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')
@@ -40,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
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to