Author: Matti Picus <[email protected]>
Branch: cpyext-pickle
Changeset: r84846:b576bccbfa9d
Date: 2016-05-31 20:37 +0300
http://bitbucket.org/pypy/pypy/changeset/b576bccbfa9d/

Log:    merge default into branch

diff too long, truncating to 2000 out of 5510 lines

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -23,3 +23,5 @@
 3260adbeba4a8b6659d1cc0d0b41f266769b74da release-5.1
 b0a649e90b6642251fb4a765fe5b27a97b1319a9 release-5.1.1
 80ef432a32d9baa4b3c5a54c215e8ebe499f6374 release-5.1.2
+40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2
+40497617ae91caa1a394d8be6f9cd2de31cb0628 release-pypy3.3-v5.2
diff --git a/lib-python/2.7/subprocess.py b/lib-python/2.7/subprocess.py
--- a/lib-python/2.7/subprocess.py
+++ b/lib-python/2.7/subprocess.py
@@ -834,54 +834,63 @@
             c2pread, c2pwrite = None, None
             errread, errwrite = None, None
 
+            ispread = False
             if stdin is None:
                 p2cread = 
_subprocess.GetStdHandle(_subprocess.STD_INPUT_HANDLE)
                 if p2cread is None:
                     p2cread, _ = _subprocess.CreatePipe(None, 0)
+                    ispread = True
             elif stdin == PIPE:
                 p2cread, p2cwrite = _subprocess.CreatePipe(None, 0)
+                ispread = True
             elif isinstance(stdin, int):
                 p2cread = msvcrt.get_osfhandle(stdin)
             else:
                 # Assuming file-like object
                 p2cread = msvcrt.get_osfhandle(stdin.fileno())
-            p2cread = self._make_inheritable(p2cread)
+            p2cread = self._make_inheritable(p2cread, ispread)
             # We just duplicated the handle, it has to be closed at the end
             to_close.add(p2cread)
             if stdin == PIPE:
                 to_close.add(p2cwrite)
 
+            ispwrite = False
             if stdout is None:
                 c2pwrite = 
_subprocess.GetStdHandle(_subprocess.STD_OUTPUT_HANDLE)
                 if c2pwrite is None:
                     _, c2pwrite = _subprocess.CreatePipe(None, 0)
+                    ispwrite = True
             elif stdout == PIPE:
                 c2pread, c2pwrite = _subprocess.CreatePipe(None, 0)
+                ispwrite = True
             elif isinstance(stdout, int):
                 c2pwrite = msvcrt.get_osfhandle(stdout)
             else:
                 # Assuming file-like object
                 c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
-            c2pwrite = self._make_inheritable(c2pwrite)
+            c2pwrite = self._make_inheritable(c2pwrite, ispwrite)
             # We just duplicated the handle, it has to be closed at the end
             to_close.add(c2pwrite)
             if stdout == PIPE:
                 to_close.add(c2pread)
 
+            ispwrite = False
             if stderr is None:
                 errwrite = 
_subprocess.GetStdHandle(_subprocess.STD_ERROR_HANDLE)
                 if errwrite is None:
                     _, errwrite = _subprocess.CreatePipe(None, 0)
+                    ispwrite = True
             elif stderr == PIPE:
                 errread, errwrite = _subprocess.CreatePipe(None, 0)
+                ispwrite = True
             elif stderr == STDOUT:
-                errwrite = c2pwrite.handle # pass id to not close it
+                errwrite = c2pwrite
             elif isinstance(stderr, int):
                 errwrite = msvcrt.get_osfhandle(stderr)
             else:
                 # Assuming file-like object
                 errwrite = msvcrt.get_osfhandle(stderr.fileno())
-            errwrite = self._make_inheritable(errwrite)
+            errwrite = self._make_inheritable(errwrite, ispwrite)
             # We just duplicated the handle, it has to be closed at the end
             to_close.add(errwrite)
             if stderr == PIPE:
@@ -892,13 +901,14 @@
                     errread, errwrite), to_close
 
 
-        def _make_inheritable(self, handle):
+        def _make_inheritable(self, handle, close=False):
             """Return a duplicate of handle, which is inheritable"""
             dupl = _subprocess.DuplicateHandle(_subprocess.GetCurrentProcess(),
                                 handle, _subprocess.GetCurrentProcess(), 0, 1,
                                 _subprocess.DUPLICATE_SAME_ACCESS)
-            # If the initial handle was obtained with CreatePipe, close it.
-            if not isinstance(handle, int):
+            # PyPy: If the initial handle was obtained with CreatePipe,
+            # close it.
+            if close:
                 handle.Close()
             return dupl
 
diff --git a/lib_pypy/_pypy_interact.py b/lib_pypy/_pypy_interact.py
--- a/lib_pypy/_pypy_interact.py
+++ b/lib_pypy/_pypy_interact.py
@@ -6,7 +6,7 @@
 irc_header = "And now for something completely different"
 
 
-def interactive_console(mainmodule=None, quiet=False):
+def interactive_console(mainmodule=None, quiet=False, future_flags=0):
     # set sys.{ps1,ps2} just before invoking the interactive interpreter. This
     # mimics what CPython does in pythonrun.c
     if not hasattr(sys, 'ps1'):
@@ -37,15 +37,17 @@
             raise ImportError
         from pyrepl.simple_interact import run_multiline_interactive_console
     except ImportError:
-        run_simple_interactive_console(mainmodule)
+        run_simple_interactive_console(mainmodule, future_flags=future_flags)
     else:
-        run_multiline_interactive_console(mainmodule)
+        run_multiline_interactive_console(mainmodule, 
future_flags=future_flags)
 
-def run_simple_interactive_console(mainmodule):
+def run_simple_interactive_console(mainmodule, future_flags=0):
     import code
     if mainmodule is None:
         import __main__ as mainmodule
     console = code.InteractiveConsole(mainmodule.__dict__, filename='<stdin>')
+    if future_flags:
+        console.compile.compiler.flags |= future_flags
     # some parts of code.py are copied here because it seems to be impossible
     # to start an interactive console without printing at least one line
     # of banner
diff --git a/lib_pypy/_subprocess.py b/lib_pypy/_subprocess.py
--- a/lib_pypy/_subprocess.py
+++ b/lib_pypy/_subprocess.py
@@ -4,6 +4,9 @@
 subprocess module on Windows.
 """
 
+import sys
+if sys.platform != 'win32':
+    raise ImportError("The '_subprocess' module is only available on Windows")
 
 # Declare external Win32 functions
 
diff --git a/lib_pypy/pyrepl/simple_interact.py 
b/lib_pypy/pyrepl/simple_interact.py
--- a/lib_pypy/pyrepl/simple_interact.py
+++ b/lib_pypy/pyrepl/simple_interact.py
@@ -43,11 +43,13 @@
         return short
     return text
 
-def run_multiline_interactive_console(mainmodule=None):
+def run_multiline_interactive_console(mainmodule=None, future_flags=0):
     import code
     if mainmodule is None:
         import __main__ as mainmodule
     console = code.InteractiveConsole(mainmodule.__dict__, filename='<stdin>')
+    if future_flags:
+        console.compile.compiler.flags |= future_flags
 
     def more_lines(unicodetext):
         # ooh, look at the hack:
diff --git a/pypy/doc/build.rst b/pypy/doc/build.rst
--- a/pypy/doc/build.rst
+++ b/pypy/doc/build.rst
@@ -70,9 +70,6 @@
 bz2
     libbz2
 
-lzma (PyPy3 only)
-    liblzma
-
 pyexpat
     libexpat1
 
@@ -98,11 +95,16 @@
 tk
     tk-dev
 
+lzma (PyPy3 only)
+    liblzma
+
+To run untranslated tests, you need the Boehm garbage collector libgc.
+
 On Debian, this is the command to install all build-time dependencies::
 
     apt-get install gcc make libffi-dev pkg-config libz-dev libbz2-dev \
     libsqlite3-dev libncurses-dev libexpat1-dev libssl-dev libgdbm-dev \
-    tk-dev libgc-dev
+    tk-dev libgc-dev liblzma-dev
 
 For the optional lzma module on PyPy3 you will also need ``liblzma-dev``.
 
diff --git a/pypy/doc/index-of-release-notes.rst 
b/pypy/doc/index-of-release-notes.rst
--- a/pypy/doc/index-of-release-notes.rst
+++ b/pypy/doc/index-of-release-notes.rst
@@ -49,6 +49,13 @@
    release-0.6
 
 
+CPython 3.3 compatible versions
+-------------------------------
+
+.. toctree::
+
+   release-pypy3.3-v5.2-alpha1.rst
+
 CPython 3.2 compatible versions
 -------------------------------
 
diff --git a/pypy/doc/release-pypy3.3-v5.2-alpha1.rst 
b/pypy/doc/release-pypy3.3-v5.2-alpha1.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-pypy3.3-v5.2-alpha1.rst
@@ -0,0 +1,69 @@
+===================
+PyPy3 v5.2 alpha 1
+===================
+
+We're pleased to announce the first alpha release of PyPy3.3 v5.2. This is the
+first release of PyPy which targets Python 3.3 (3.3.5) compatibility.
+
+We would like to thank all of the people who donated_ to the `py3k proposal`_
+for supporting the work that went into this and future releases.
+
+You can download the PyPy3.3 v5.2 alpha 1 release here:
+
+    http://pypy.org/download.html#python-3-3-5-compatible-pypy3-3-v5-2
+
+Highlights
+==========
+
+* Python 3.3.5 support!
+
+  - Being an early alpha release, there are some `missing features`_ such as a
+    `PEP 393-like space efficient string representation`_ and `known issues`_
+    including performance regressions (e.g. issue `#2305`_). The focus for this
+    release has been updating to 3.3 compatibility. Windows is also not yet
+    supported.
+
+* `ensurepip`_ is also included (it's only included in CPython 3 >= 3.4).
+
+What is PyPy?
+==============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7.10 and one day 3.3.5. It's fast due to its integrated tracing JIT
+compiler.
+
+We also welcome developers of other `dynamic languages`_ to see what RPython
+can do for them.
+
+This release supports:
+
+  * **x86** machines on most common operating systems except Windows
+    (Linux 32/64, Mac OS X 64, OpenBSD, FreeBSD),
+
+  * newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux,
+
+  * big- and little-endian variants of **PPC64** running Linux,
+
+  * **s390x** running Linux
+
+Please try it out and let us know what you think. We welcome feedback, we know
+you are using PyPy, please tell us about it!
+
+We'd especially like to thank these people for their contributions to this
+release:
+
+Manuel Jacob, Ronan Lamy, Mark Young, Amaury Forgeot d'Arc, Philip Jenvey,
+Martin Matusiak, Vasily Kuznetsov, Matti Picus, Armin Rigo and many others.
+
+Cheers
+
+The PyPy Team
+
+.. _donated: 
http://morepypy.blogspot.com/2012/01/py3k-and-numpy-first-stage-thanks-to.html
+.. _`py3k proposal`: http://pypy.org/py3donate.html
+.. _`PEP 393-like space efficient string representation`: 
https://bitbucket.org/pypy/pypy/issues/2309/optimized-unicode-representation
+.. _`missing features`: 
https://bitbucket.org/pypy/pypy/issues?status=new&status=open&component=PyPy3+%28running+Python+3.x%29&kind=enhancement
+.. _`known issues`: 
https://bitbucket.org/pypy/pypy/issues?status=new&status=open&component=PyPy3%20%28running%20Python%203.x%29
+.. _`#2305`: https://bitbucket.org/pypy/pypy/issues/2305
+.. _`ensurepip`: 
https://docs.python.org/3/library/ensurepip.html#module-ensurepip
+.. _`dynamic languages`: http://pypyjs.org
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
@@ -105,3 +105,24 @@
 Fix some warnings when compiling CPython C extension modules
 
 .. branch: syntax_fix
+
+.. branch: remove-raisingops
+
+Remove most of the _ovf, _zer and _val operations from RPython.  Kills
+quite some code internally, and allows the JIT to do better
+optimizations: for example, app-level code like ``x / 2`` or ``x % 2``
+can now be turned into ``x >> 1`` or ``x & 1``, even if x is possibly
+negative.
+
+.. branch: cpyext-old-buffers
+
+Generalize cpyext old-style buffers to more than just str/buffer, add support 
for mmap
+
+.. branch: numpy-includes
+
+Move _numpypy headers into a directory so they are not picked up by upstream 
numpy, scipy
+This allows building upstream numpy and scipy in pypy via cpyext
+
+.. branch: traceviewer-common-merge-point-formats
+
+Teach RPython JIT's off-line traceviewer the most common ``debug_merge_point`` 
formats.
\ No newline at end of file
diff --git a/pypy/doc/whatsnew-pypy3-5.1.1-alpha1.rst 
b/pypy/doc/whatsnew-pypy3-5.1.1-alpha1.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/whatsnew-pypy3-5.1.1-alpha1.rst
@@ -0,0 +1,10 @@
+=================================
+What's new in PyPy3 5.1.1 alpha 1
+=================================
+
+.. A recent revision, ignoring all other branches for this release
+.. startrev: 29d14733e007
+
+.. branch: py3.3
+
+Python 3.3 compatibility
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -238,6 +238,15 @@
 for use. The release packaging script will pick up the tcltk runtime in the lib
 directory and put it in the archive.
 
+The lzma compression library
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Python 3.3 ship with CFFI wrappers for the lzma library, which can be
+downloaded from this site http://tukaani.org/xz. Python 3.3-3.5 use version
+5.0.5, a prebuilt version can be downloaded from
+http://tukaani.org/xz/xz-5.0.5-windows.zip, check the signature
+http://tukaani.org/xz/xz-5.0.5-windows.zip.sig
+
 
 Using the mingw compiler
 ------------------------
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -583,6 +583,12 @@
         if hasattr(signal, 'SIGXFSZ'):
             signal.signal(signal.SIGXFSZ, signal.SIG_IGN)
 
+    # Pre-load the default encoder (controlled by PYTHONIOENCODING) now.
+    # This is needed before someone mucks up with sys.path (or even adds
+    # a unicode string to it, leading to infinite recursion when we try
+    # to encode it during importing).  Note: very obscure.  Issue #2314.
+    str(u'')
+
     def inspect_requested():
         # We get an interactive prompt in one of the following three cases:
         #
@@ -603,6 +609,11 @@
                 ((inspect or (readenv and real_getenv('PYTHONINSPECT')))
                  and sys.stdin.isatty()))
 
+    try:
+        from _ast import PyCF_ACCEPT_NULL_BYTES
+    except ImportError:
+        PyCF_ACCEPT_NULL_BYTES = 0
+    future_flags = [0]
     success = True
 
     try:
@@ -613,7 +624,9 @@
 
             @hidden_applevel
             def run_it():
-                exec run_command in mainmodule.__dict__
+                co_cmd = compile(run_command, '<module>', 'exec')
+                exec co_cmd in mainmodule.__dict__
+                future_flags[0] = co_cmd.co_flags
             success = run_toplevel(run_it)
         elif run_module:
             # handle the "-m" command
@@ -625,11 +638,6 @@
             # handle the case where no command/filename/module is specified
             # on the command-line.
 
-            try:
-                from _ast import PyCF_ACCEPT_NULL_BYTES
-            except ImportError:
-                PyCF_ACCEPT_NULL_BYTES = 0
-
             # update sys.path *after* loading site.py, in case there is a
             # "site.py" file in the script's directory. Only run this if we're
             # executing the interactive prompt, if we're running a script we
@@ -656,6 +664,7 @@
                                                         'exec',
                                                         PyCF_ACCEPT_NULL_BYTES)
                             exec co_python_startup in mainmodule.__dict__
+                            future_flags[0] = co_python_startup.co_flags
                         mainmodule.__file__ = python_startup
                         run_toplevel(run_it)
                         try:
@@ -673,6 +682,7 @@
                     co_stdin = compile(sys.stdin.read(), '<stdin>', 'exec',
                                        PyCF_ACCEPT_NULL_BYTES)
                     exec co_stdin in mainmodule.__dict__
+                    future_flags[0] = co_stdin.co_flags
                 mainmodule.__file__ = '<stdin>'
                 success = run_toplevel(run_it)
         else:
@@ -702,7 +712,20 @@
                     args = (runpy._run_module_as_main, '__main__', False)
                 else:
                     # no.  That's the normal path, "pypy stuff.py".
-                    args = (execfile, filename, mainmodule.__dict__)
+                    # This includes the logic from execfile(), tweaked
+                    # to grab the future_flags at the end.
+                    @hidden_applevel
+                    def run_it():
+                        f = file(filename, 'rU')
+                        try:
+                            source = f.read()
+                        finally:
+                            f.close()
+                        co_main = compile(source.rstrip()+"\n", filename,
+                                          'exec', PyCF_ACCEPT_NULL_BYTES)
+                        exec co_main in mainmodule.__dict__
+                        future_flags[0] = co_main.co_flags
+                    args = (run_it,)
             success = run_toplevel(*args)
 
     except SystemExit as e:
@@ -715,12 +738,21 @@
     # start a prompt if requested
     if inspect_requested():
         try:
+            import __future__
             from _pypy_interact import interactive_console
             pypy_version_info = getattr(sys, 'pypy_version_info', 
sys.version_info)
             irc_topic = pypy_version_info[3] != 'final' or (
                             readenv and os.getenv('PYPY_IRC_TOPIC'))
+            flags = 0
+            for fname in __future__.all_feature_names:
+                feature = getattr(__future__, fname)
+                if future_flags[0] & feature.compiler_flag:
+                    flags |= feature.compiler_flag
+            kwds = {}
+            if flags:
+                kwds['future_flags'] = flags
             success = run_toplevel(interactive_console, mainmodule,
-                                   quiet=not irc_topic)
+                                   quiet=not irc_topic, **kwds)
         except SystemExit as e:
             status = e.code
         else:
diff --git a/pypy/interpreter/test/test_app_main.py 
b/pypy/interpreter/test/test_app_main.py
--- a/pypy/interpreter/test/test_app_main.py
+++ b/pypy/interpreter/test/test_app_main.py
@@ -76,6 +76,11 @@
     print 'Goodbye2'   # should not be reached
     """)
 
+script_with_future = getscript("""
+    from __future__ import division
+    from __future__ import print_function
+    """)
+
 
 class TestParseCommandLine:
     def check_options(self, options, sys_argv, **expected):
@@ -445,6 +450,31 @@
         finally:
             os.environ['PYTHONSTARTUP'] = old
 
+    def test_future_in_executed_script(self):
+        child = self.spawn(['-i', script_with_future])
+        child.expect('>>> ')
+        child.sendline('x=1; print(x/2, 3/4)')
+        child.expect('0.5 0.75')
+
+    def test_future_in_python_startup(self, monkeypatch):
+        monkeypatch.setenv('PYTHONSTARTUP', script_with_future)
+        child = self.spawn([])
+        child.expect('>>> ')
+        child.sendline('x=1; print(x/2, 3/4)')
+        child.expect('0.5 0.75')
+
+    def test_future_in_cmd(self):
+        child = self.spawn(['-i', '-c', 'from __future__ import division'])
+        child.expect('>>> ')
+        child.sendline('x=1; x/2; 3/4')
+        child.expect('0.5')
+        child.expect('0.75')
+
+    def test_cmd_co_name(self):
+        child = self.spawn(['-c',
+                    'import sys; print sys._getframe(0).f_code.co_name'])
+        child.expect('<module>')
+
     def test_ignore_python_inspect(self):
         os.environ['PYTHONINSPECT_'] = '1'
         try:
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -12,7 +12,8 @@
 
 
 class TypeDef(object):
-    def __init__(self, __name, __base=None, __total_ordering__=None, 
**rawdict):
+    def __init__(self, __name, __base=None, __total_ordering__=None,
+                 __buffer=None, **rawdict):
         "NOT_RPYTHON: initialization-time only"
         self.name = __name
         if __base is None:
@@ -22,6 +23,8 @@
         else:
             bases = [__base]
         self.bases = bases
+        assert __buffer in {None, 'read-write', 'read'}, "Unknown value for 
__buffer"
+        self.buffer = __buffer
         self.heaptype = False
         self.hasdict = '__dict__' in rawdict
         # no __del__: use an RPython _finalize_() method and register_finalizer
diff --git a/pypy/module/__pypy__/interp_intop.py 
b/pypy/module/__pypy__/interp_intop.py
--- a/pypy/module/__pypy__/interp_intop.py
+++ b/pypy/module/__pypy__/interp_intop.py
@@ -2,6 +2,19 @@
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rlib.rarithmetic import r_uint, intmask
+from rpython.rlib import jit
+
+
+# XXX maybe temporary: hide llop.int_{floordiv,mod} from the JIT,
+#     because now it expects only Python-style divisions, not the
+#     C-style divisions of these two ll operations
[email protected]_look_inside
+def _int_floordiv(n, m):
+    return llop.int_floordiv(lltype.Signed, n, m)
+
[email protected]_look_inside
+def _int_mod(n, m):
+    return llop.int_mod(lltype.Signed, n, m)
 
 
 @unwrap_spec(n=int, m=int)
@@ -18,11 +31,11 @@
 
 @unwrap_spec(n=int, m=int)
 def int_floordiv(space, n, m):
-    return space.wrap(llop.int_floordiv(lltype.Signed, n, m))
+    return space.wrap(_int_floordiv(n, m))
 
 @unwrap_spec(n=int, m=int)
 def int_mod(space, n, m):
-    return space.wrap(llop.int_mod(lltype.Signed, n, m))
+    return space.wrap(_int_mod(n, m))
 
 @unwrap_spec(n=int, m=int)
 def int_lshift(space, n, m):
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -161,12 +161,13 @@
 
     if copy_numpy_headers:
         try:
-            dstdir.mkdir('numpy')
+            dstdir.mkdir('_numpypy')
+            dstdir.mkdir('_numpypy/numpy')
         except py.error.EEXIST:
             pass
-        numpy_dstdir = dstdir / 'numpy'
+        numpy_dstdir = dstdir / '_numpypy' / 'numpy'
 
-        numpy_include_dir = include_dir / 'numpy'
+        numpy_include_dir = include_dir / '_numpypy' / 'numpy'
         numpy_headers = numpy_include_dir.listdir('*.h') + 
numpy_include_dir.listdir('*.inl')
         _copy_header_files(numpy_headers, numpy_dstdir)
 
diff --git a/pypy/module/cpyext/include/numpy/README 
b/pypy/module/cpyext/include/_numpypy/numpy/README
rename from pypy/module/cpyext/include/numpy/README
rename to pypy/module/cpyext/include/_numpypy/numpy/README
diff --git a/pypy/module/cpyext/include/numpy/__multiarray_api.h 
b/pypy/module/cpyext/include/_numpypy/numpy/__multiarray_api.h
rename from pypy/module/cpyext/include/numpy/__multiarray_api.h
rename to pypy/module/cpyext/include/_numpypy/numpy/__multiarray_api.h
diff --git a/pypy/module/cpyext/include/numpy/arrayobject.h 
b/pypy/module/cpyext/include/_numpypy/numpy/arrayobject.h
rename from pypy/module/cpyext/include/numpy/arrayobject.h
rename to pypy/module/cpyext/include/_numpypy/numpy/arrayobject.h
diff --git a/pypy/module/cpyext/include/numpy/ndarraytypes.h 
b/pypy/module/cpyext/include/_numpypy/numpy/ndarraytypes.h
rename from pypy/module/cpyext/include/numpy/ndarraytypes.h
rename to pypy/module/cpyext/include/_numpypy/numpy/ndarraytypes.h
diff --git a/pypy/module/cpyext/include/numpy/npy_3kcompat.h 
b/pypy/module/cpyext/include/_numpypy/numpy/npy_3kcompat.h
rename from pypy/module/cpyext/include/numpy/npy_3kcompat.h
rename to pypy/module/cpyext/include/_numpypy/numpy/npy_3kcompat.h
diff --git a/pypy/module/cpyext/include/numpy/npy_common.h 
b/pypy/module/cpyext/include/_numpypy/numpy/npy_common.h
rename from pypy/module/cpyext/include/numpy/npy_common.h
rename to pypy/module/cpyext/include/_numpypy/numpy/npy_common.h
diff --git a/pypy/module/cpyext/include/numpy/old_defines.h 
b/pypy/module/cpyext/include/_numpypy/numpy/old_defines.h
rename from pypy/module/cpyext/include/numpy/old_defines.h
rename to pypy/module/cpyext/include/_numpypy/numpy/old_defines.h
diff --git a/pypy/module/cpyext/include/cStringIO.h 
b/pypy/module/cpyext/include/cStringIO.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/include/cStringIO.h
@@ -0,0 +1,73 @@
+#ifndef Py_CSTRINGIO_H
+#define Py_CSTRINGIO_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+
+  This header provides access to cStringIO objects from C.
+  Functions are provided for calling cStringIO objects and
+  macros are provided for testing whether you have cStringIO
+  objects.
+
+  Before calling any of the functions or macros, you must initialize
+  the routines with:
+
+    PycString_IMPORT
+
+  This would typically be done in your init function.
+
+*/
+
+#define PycStringIO_CAPSULE_NAME "cStringIO.cStringIO_CAPI"
+
+#define PycString_IMPORT \
+  PycStringIO = ((struct PycStringIO_CAPI*)PyCapsule_Import(\
+    PycStringIO_CAPSULE_NAME, 0))
+
+/* Basic functions to manipulate cStringIO objects from C */
+
+static struct PycStringIO_CAPI {
+
+ /* Read a string from an input object.  If the last argument
+    is -1, the remainder will be read.
+    */
+  int(*cread)(PyObject *, char **, Py_ssize_t);
+
+ /* Read a line from an input object.  Returns the length of the read
+    line as an int and a pointer inside the object buffer as char** (so
+    the caller doesn't have to provide its own buffer as destination).
+    */
+  int(*creadline)(PyObject *, char **);
+
+  /* Write a string to an output object*/
+  int(*cwrite)(PyObject *, const char *, Py_ssize_t);
+
+  /* Get the output object as a Python string (returns new reference). */
+  PyObject *(*cgetvalue)(PyObject *);
+
+  /* Create a new output object */
+  PyObject *(*NewOutput)(int);
+
+  /* Create an input object from a Python string
+     (copies the Python string reference).
+     */
+  PyObject *(*NewInput)(PyObject *);
+
+  /* The Python types for cStringIO input and output objects.
+     Note that you can do input on an output object.
+     */
+  PyTypeObject *InputType, *OutputType;
+
+} *PycStringIO;
+
+/* These can be used to test if you have one */
+#define PycStringIO_InputCheck(O) \
+  (0) /* Py_TYPE(O)==PycStringIO->InputType) */
+#define PycStringIO_OutputCheck(O) \
+  (0) /* Py_TYPE(O)==PycStringIO->OutputType) */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_CSTRINGIO_H */
diff --git a/pypy/module/cpyext/src/ndarrayobject.c 
b/pypy/module/cpyext/src/ndarrayobject.c
--- a/pypy/module/cpyext/src/ndarrayobject.c
+++ b/pypy/module/cpyext/src/ndarrayobject.c
@@ -1,7 +1,7 @@
 
 #include "Python.h"
 #include "pypy_numpy.h"
-#include "numpy/arrayobject.h"
+#include "_numpypy/numpy/arrayobject.h"
 #include <string.h>   /* memset, memcpy */
 
 void 
diff --git a/pypy/module/cpyext/test/test_abstract.py 
b/pypy/module/cpyext/test/test_abstract.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/test_abstract.py
@@ -0,0 +1,106 @@
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+import pytest
+
+class AppTestBufferProtocol(AppTestCpythonExtensionBase):
+    """Tests for the old buffer protocol."""
+
+    def w_get_buffer_support(self):
+        return self.import_extension('buffer_support', [
+            ("charbuffer_as_string", "METH_O",
+             """
+                 char *ptr;
+                 Py_ssize_t size;
+                 if (PyObject_AsCharBuffer(args, &ptr, &size) < 0)
+                     return NULL;
+                 return PyString_FromStringAndSize(ptr, size);
+             """),
+            ("check_readbuffer", "METH_O",
+             """
+                 return PyBool_FromLong(PyObject_CheckReadBuffer(args));
+             """),
+            ("readbuffer_as_string", "METH_O",
+             """
+                 const void *ptr;
+                 Py_ssize_t size;
+                 if (PyObject_AsReadBuffer(args, &ptr, &size) < 0)
+                     return NULL;
+                 return PyString_FromStringAndSize((char*)ptr, size);
+             """),
+            ("writebuffer_as_string", "METH_O",
+             """
+                 void *ptr;
+                 Py_ssize_t size;
+                 if (PyObject_AsWriteBuffer(args, &ptr, &size) < 0)
+                     return NULL;
+                 return PyString_FromStringAndSize((char*)ptr, size);
+             """),
+            ("zero_out_writebuffer", "METH_O",
+             """
+                 void *ptr;
+                 Py_ssize_t size;
+                 Py_ssize_t i;
+                 if (PyObject_AsWriteBuffer(args, &ptr, &size) < 0)
+                     return NULL;
+                 for (i = 0; i < size; i++) {
+                     ((char*)ptr)[i] = 0;
+                 }
+                 Py_RETURN_NONE;
+             """),
+            ])
+
+    def test_string(self):
+        buffer_support = self.get_buffer_support()
+
+        s = 'a\0x'
+
+        assert buffer_support.check_readbuffer(s)
+        assert s == buffer_support.readbuffer_as_string(s)
+        assert raises(TypeError, buffer_support.writebuffer_as_string, s)
+        assert s == buffer_support.charbuffer_as_string(s)
+
+    def test_buffer(self):
+        buffer_support = self.get_buffer_support()
+
+        s = 'a\0x'
+        buf = buffer(s)
+
+        assert buffer_support.check_readbuffer(buf)
+        assert s == buffer_support.readbuffer_as_string(buf)
+        assert raises(TypeError, buffer_support.writebuffer_as_string, buf)
+        assert s == buffer_support.charbuffer_as_string(buf)
+
+    def test_mmap(self):
+        import mmap
+        buffer_support = self.get_buffer_support()
+
+        s = 'a\0x'
+        mm = mmap.mmap(-1, 3)
+        mm[:] = s
+
+        assert buffer_support.check_readbuffer(mm)
+        assert s == buffer_support.readbuffer_as_string(mm)
+        assert s == buffer_support.writebuffer_as_string(mm)
+        assert s == buffer_support.charbuffer_as_string(mm)
+
+        s = '\0' * 3
+        buffer_support.zero_out_writebuffer(mm)
+        assert s == ''.join(mm)
+        assert s == buffer_support.readbuffer_as_string(mm)
+        assert s == buffer_support.writebuffer_as_string(mm)
+        assert s == buffer_support.charbuffer_as_string(mm)
+
+        s = '\0' * 3
+        ro_mm = mmap.mmap(-1, 3, access=mmap.ACCESS_READ)
+        assert buffer_support.check_readbuffer(ro_mm)
+        assert s == buffer_support.readbuffer_as_string(ro_mm)
+        assert raises(TypeError, buffer_support.writebuffer_as_string, ro_mm)
+        assert s == buffer_support.charbuffer_as_string(ro_mm)
+
+    def test_nonbuffer(self):
+        # e.g. int
+        buffer_support = self.get_buffer_support()
+
+        assert not buffer_support.check_readbuffer(42)
+        assert raises(TypeError, buffer_support.readbuffer_as_string, 42)
+        assert raises(TypeError, buffer_support.writebuffer_as_string, 42)
+        assert raises(TypeError, buffer_support.charbuffer_as_string, 42)
diff --git a/pypy/module/cpyext/test/test_bytesobject.py 
b/pypy/module/cpyext/test/test_bytesobject.py
--- a/pypy/module/cpyext/test/test_bytesobject.py
+++ b/pypy/module/cpyext/test/test_bytesobject.py
@@ -415,12 +415,15 @@
         lenp = lltype.malloc(Py_ssize_tP.TO, 1, flavor='raw')
 
         w_text = space.wrap("text")
-        assert api.PyObject_AsCharBuffer(w_text, bufp, lenp) == 0
+        ref = make_ref(space, w_text)
+        prev_refcnt = ref.c_ob_refcnt
+        assert api.PyObject_AsCharBuffer(ref, bufp, lenp) == 0
+        assert ref.c_ob_refcnt == prev_refcnt
         assert lenp[0] == 4
         assert rffi.charp2str(bufp[0]) == 'text'
-
         lltype.free(bufp, flavor='raw')
         lltype.free(lenp, flavor='raw')
+        api.Py_DecRef(ref)
 
     def test_intern(self, space, api):
         buf = rffi.str2charp("test")
diff --git a/pypy/module/cpyext/test/test_cpyext.py 
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -136,7 +136,7 @@
     """Base class for all cpyext tests."""
     spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array',
                                    'itertools', 'time', 'binascii',
-                                   'micronumpy',
+                                   'micronumpy', 'mmap'
                                    ])
 
     enable_leak_checking = True
diff --git a/pypy/module/cpyext/test/test_ndarrayobject.py 
b/pypy/module/cpyext/test/test_ndarrayobject.py
--- a/pypy/module/cpyext/test/test_ndarrayobject.py
+++ b/pypy/module/cpyext/test/test_ndarrayobject.py
@@ -1,4 +1,5 @@
 import py
+import os
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 from rpython.rtyper.lltypesystem import rffi, lltype
@@ -236,8 +237,10 @@
             except:
                 skip('numpy not importable')
         else:
-            cls.w_numpy_include = cls.space.wrap([])
-            
+            numpy_incl = os.path.abspath(os.path.dirname(__file__) + 
+                                         '/../include/_numpypy')
+            assert os.path.exists(numpy_incl)
+            cls.w_numpy_include = cls.space.wrap([numpy_incl])
 
     def test_ndarray_object_c(self):
         mod = self.import_extension('foo', [
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -486,13 +486,40 @@
 
 @cpython_api([PyObject, Py_ssize_tP], lltype.Signed, header=None,
              error=CANNOT_FAIL)
-def str_segcount(space, w_obj, ref):
+def bf_segcount(space, w_obj, ref):
     if ref:
         ref[0] = space.len_w(w_obj)
     return 1
 
 @cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
              header=None, error=-1)
+def bf_getreadbuffer(space, w_buf, segment, ref):
+    if segment != 0:
+        raise oefmt(space.w_SystemError,
+                    "accessing non-existent segment")
+    buf = space.readbuf_w(w_buf)
+    address = buf.get_raw_address()
+    ref[0] = address
+    return len(buf)
+
+@cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
+             header=None, error=-1)
+def bf_getcharbuffer(space, w_buf, segment, ref):
+    return bf_getreadbuffer(space, w_buf, segment, rffi.cast(rffi.VOIDPP, ref))
+
+@cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
+             header=None, error=-1)
+def bf_getwritebuffer(space, w_buf, segment, ref):
+    if segment != 0:
+        raise oefmt(space.w_SystemError,
+                    "accessing non-existent segment")
+
+    buf = space.writebuf_w(w_buf)
+    ref[0] = buf.get_raw_address()
+    return len(buf)
+
+@cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
+             header=None, error=-1)
 def str_getreadbuffer(space, w_str, segment, ref):
     from pypy.module.cpyext.bytesobject import PyString_AsString
     if segment != 0:
@@ -506,16 +533,8 @@
 
 @cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
              header=None, error=-1)
-def str_getcharbuffer(space, w_str, segment, ref):
-    from pypy.module.cpyext.bytesobject import PyString_AsString
-    if segment != 0:
-        raise oefmt(space.w_SystemError,
-                    "accessing non-existent string segment")
-    pyref = make_ref(space, w_str)
-    ref[0] = PyString_AsString(space, pyref)
-    # Stolen reference: the object has better exist somewhere else
-    Py_DecRef(space, pyref)
-    return space.len_w(w_str)
+def str_getcharbuffer(space, w_buf, segment, ref):
+    return str_getreadbuffer(space, w_buf, segment, rffi.cast(rffi.VOIDPP, 
ref))
 
 @cpython_api([PyObject, Py_ssize_t, rffi.VOIDPP], lltype.Signed,
              header=None, error=-1)
@@ -523,33 +542,59 @@
     from pypy.module.cpyext.bufferobject import PyBufferObject
     if segment != 0:
         raise oefmt(space.w_SystemError,
-                    "accessing non-existent string segment")
+                    "accessing non-existent buffer segment")
     py_buf = rffi.cast(PyBufferObject, pyref)
     ref[0] = py_buf.c_b_ptr
-    #Py_DecRef(space, pyref)
     return py_buf.c_b_size
 
-def setup_string_buffer_procs(space, pto):
+@cpython_api([PyObject, Py_ssize_t, rffi.CCHARPP], lltype.Signed,
+             header=None, error=-1)
+def buf_getcharbuffer(space, w_buf, segment, ref):
+    return buf_getreadbuffer(space, w_buf, segment, rffi.cast(rffi.VOIDPP, 
ref))
+
+def setup_buffer_procs(space, w_type, pto):
+    bufspec = w_type.layout.typedef.buffer
+    if bufspec is None:
+        # not a buffer
+        return
     c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True)
     lltype.render_immortal(c_buf)
-    c_buf.c_bf_getsegcount = llhelper(str_segcount.api_func.functype,
-                                      str_segcount.api_func.get_wrapper(space))
-    c_buf.c_bf_getreadbuffer = llhelper(str_getreadbuffer.api_func.functype,
-                                 str_getreadbuffer.api_func.get_wrapper(space))
-    c_buf.c_bf_getcharbuffer = llhelper(str_getcharbuffer.api_func.functype,
-                                 str_getcharbuffer.api_func.get_wrapper(space))
+    c_buf.c_bf_getsegcount = llhelper(bf_segcount.api_func.functype,
+                                      bf_segcount.api_func.get_wrapper(space))
+    if space.is_w(w_type, space.w_str):
+        # Special case: str doesn't support get_raw_address(), so we have a
+        # custom get*buffer that instead gives the address of the char* in the
+        # PyStringObject*!
+        c_buf.c_bf_getreadbuffer = llhelper(
+            str_getreadbuffer.api_func.functype,
+            str_getreadbuffer.api_func.get_wrapper(space))
+        c_buf.c_bf_getcharbuffer = llhelper(
+            str_getcharbuffer.api_func.functype,
+            str_getcharbuffer.api_func.get_wrapper(space))
+    elif space.is_w(w_type, space.w_buffer):
+        # Special case: we store a permanent address on the cpyext wrapper,
+        # so we'll reuse that.
+        # Note: we could instead store a permanent address on the buffer 
object,
+        # and use get_raw_address()
+        c_buf.c_bf_getreadbuffer = llhelper(
+            buf_getreadbuffer.api_func.functype,
+            buf_getreadbuffer.api_func.get_wrapper(space))
+        c_buf.c_bf_getcharbuffer = llhelper(
+            buf_getcharbuffer.api_func.functype,
+            buf_getcharbuffer.api_func.get_wrapper(space))
+    else:
+        # use get_raw_address()
+        c_buf.c_bf_getreadbuffer = llhelper(bf_getreadbuffer.api_func.functype,
+                                    
bf_getreadbuffer.api_func.get_wrapper(space))
+        c_buf.c_bf_getcharbuffer = llhelper(bf_getcharbuffer.api_func.functype,
+                                    
bf_getcharbuffer.api_func.get_wrapper(space))
+        if bufspec == 'read-write':
+            c_buf.c_bf_getwritebuffer = llhelper(
+                bf_getwritebuffer.api_func.functype,
+                bf_getwritebuffer.api_func.get_wrapper(space))
     pto.c_tp_as_buffer = c_buf
     pto.c_tp_flags |= Py_TPFLAGS_HAVE_GETCHARBUFFER
 
-def setup_buffer_buffer_procs(space, pto):
-    c_buf = lltype.malloc(PyBufferProcs, flavor='raw', zero=True)
-    lltype.render_immortal(c_buf)
-    c_buf.c_bf_getsegcount = llhelper(str_segcount.api_func.functype,
-                                      str_segcount.api_func.get_wrapper(space))
-    c_buf.c_bf_getreadbuffer = llhelper(buf_getreadbuffer.api_func.functype,
-                                 buf_getreadbuffer.api_func.get_wrapper(space))
-    pto.c_tp_as_buffer = c_buf
-
 @cpython_api([PyObject], lltype.Void, header=None)
 def type_dealloc(space, obj):
     from pypy.module.cpyext.object import PyObject_dealloc
@@ -613,10 +658,7 @@
             subtype_dealloc.api_func.functype,
             subtype_dealloc.api_func.get_wrapper(space))
     # buffer protocol
-    if space.is_w(w_type, space.w_str):
-        setup_string_buffer_procs(space, pto)
-    if space.is_w(w_type, space.w_buffer):
-        setup_buffer_buffer_procs(space, pto)
+    setup_buffer_procs(space, w_type, pto)
 
     pto.c_tp_free = llhelper(PyObject_Free.api_func.functype,
             PyObject_Free.api_func.get_wrapper(space))
diff --git a/pypy/module/micronumpy/compile.py 
b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -125,7 +125,8 @@
         return None
 
     def issubtype_w(self, w_sub, w_type):
-        return w_sub is w_type
+        is_root(w_type)
+        return NonConstant(True)
 
     def isinstance_w(self, w_obj, w_tp):
         try:
@@ -414,6 +415,10 @@
     def warn(self, w_msg, w_warn_type):
         pass
 
+def is_root(w_obj):
+    assert isinstance(w_obj, W_Root)
+is_root.expecting = W_Root
+
 class FloatObject(W_Root):
     tp = FakeSpace.w_float
     def __init__(self, floatval):
diff --git a/pypy/module/mmap/interp_mmap.py b/pypy/module/mmap/interp_mmap.py
--- a/pypy/module/mmap/interp_mmap.py
+++ b/pypy/module/mmap/interp_mmap.py
@@ -280,7 +280,7 @@
             raise mmap_error(space, e)
         return space.wrap(self)
 
-W_MMap.typedef = TypeDef("mmap.mmap",
+W_MMap.typedef = TypeDef("mmap.mmap", None, None, "read-write",
     __new__ = interp2app(mmap),
     close = interp2app(W_MMap.close),
     read_byte = interp2app(W_MMap.read_byte),
diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py 
b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
--- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
@@ -262,7 +262,7 @@
             [i0]
             i1 = int_add(i0, 1)
             i2 = int_sub(i1, 10)
-            i3 = int_floordiv(i2, 100)
+            i3 = int_xor(i2, 100)
             i4 = int_mul(i1, 1000)
             jump(i4)
         """
@@ -298,7 +298,7 @@
             [i0]
             i1 = int_add(i0, 1)
             i2 = int_sub(i1, 10)
-            i3 = int_floordiv(i2, 100)
+            i3 = int_xor(i2, 100)
             i4 = int_mul(i1, 1000)
             jump(i4)
         """
diff --git a/pypy/module/pypyjit/test_pypy_c/test_shift.py 
b/pypy/module/pypyjit/test_pypy_c/test_shift.py
--- a/pypy/module/pypyjit/test_pypy_c/test_shift.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_shift.py
@@ -47,26 +47,74 @@
             res = 0
             a = 0
             while a < 300:
-                assert a >= 0
-                assert 0 <= b <= 10
-                res = a/b     # ID: div
+                res1 = a/b     # ID: div
+                res2 = a/2     # ID: shift
+                res3 = a/11    # ID: mul
+                res += res1 + res2 + res3
                 a += 1
             return res
         #
         log = self.run(main, [3])
-        assert log.result == 99
+        assert log.result == main(3)
         loop, = log.loops_by_filename(self.filepath)
-        if sys.maxint == 2147483647:
-            SHIFT = 31
+        assert loop.match_by_id('div', """
+            i56 = int_eq(i48, %d)
+            i57 = int_and(i56, i37)
+            guard_false(i57, descr=...)
+            i1 = call_i(_, i48, i3, descr=...)
+        """ % (-sys.maxint-1,))
+        assert loop.match_by_id('shift', """
+            i1 = int_rshift(i2, 1)
+        """)
+        if sys.maxint > 2**32:
+            args = (63, -5030930201920786804, 3)
         else:
-            SHIFT = 63
-        assert loop.match_by_id('div', """
-            i10 = int_floordiv(i6, i7)
-            i11 = int_mul(i10, i7)
-            i12 = int_sub(i6, i11)
-            i14 = int_rshift(i12, %d)
-            i15 = int_add(i10, i14)
-        """ % SHIFT)
+            args = (31, -1171354717, 3)
+        assert loop.match_by_id('mul', """
+            i2 = int_rshift(i1, %d)
+            i3 = int_xor(i1, i2)
+            i4 = uint_mul_high(i3, %d)
+            i5 = uint_rshift(i4, %d)
+            i6 = int_xor(i5, i2)
+        """ % args)
+
+    def test_modulo_optimization(self):
+        def main(b):
+            res = 0
+            a = 0
+            while a < 300:
+                res1 = a%b     # ID: mod
+                res2 = a%2     # ID: and
+                res3 = a%11    # ID: mul
+                res += res1 + res2 + res3
+                a += 1
+            return res
+        #
+        log = self.run(main, [3])
+        assert log.result == main(3)
+        loop, = log.loops_by_filename(self.filepath)
+        assert loop.match_by_id('mod', """
+            i56 = int_eq(i48, %d)
+            i57 = int_and(i56, i37)
+            guard_false(i57, descr=...)
+            i1 = call_i(_, i48, i3, descr=...)
+        """ % (-sys.maxint-1,))
+        assert loop.match_by_id('and', """
+            i1 = int_and(i2, 1)
+        """)
+        if sys.maxint > 2**32:
+            args = (63, -5030930201920786804, 3)
+        else:
+            args = (31, -1171354717, 3)
+        assert loop.match_by_id('mul', """
+            i2 = int_rshift(i1, %d)
+            i3 = int_xor(i1, i2)
+            i4 = uint_mul_high(i3, %d)
+            i5 = uint_rshift(i4, %d)
+            i6 = int_xor(i5, i2)
+            i7 = int_mul(i6, 11)
+            i8 = int_sub(i1, i7)
+        """ % args)
 
     def test_division_to_rshift_allcases(self):
         """
diff --git a/pypy/module/pypyjit/test_pypy_c/test_string.py 
b/pypy/module/pypyjit/test_pypy_c/test_string.py
--- a/pypy/module/pypyjit/test_pypy_c/test_string.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_string.py
@@ -1,11 +1,6 @@
 import sys
 from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
 
-if sys.maxint == 2147483647:
-    SHIFT = 31
-else:
-    SHIFT = 63
-
 # XXX review the <Call> descrs to replace some EF=5 with EF=4 (elidable)
 
 
@@ -28,10 +23,7 @@
             guard_true(i14, descr=...)
             guard_not_invalidated(descr=...)
             i16 = int_eq(i6, %d)
-            i15 = int_mod(i6, i10)
-            i17 = int_rshift(i15, %d)
-            i18 = int_and(i10, i17)
-            i19 = int_add(i15, i18)
+            i19 = call_i(ConstClass(ll_int_mod__Signed_Signed), i6, i10, 
descr=<Calli . ii EF=0 OS=14>)
             i21 = int_lt(i19, 0)
             guard_false(i21, descr=...)
             i22 = int_ge(i19, i10)
@@ -49,7 +41,7 @@
             i34 = int_add(i6, 1)
             --TICK--
             jump(..., descr=...)
-        """ % (-sys.maxint-1, SHIFT))
+        """ % (-sys.maxint-1,))
 
     def test_long(self):
         def main(n):
@@ -62,19 +54,25 @@
         log = self.run(main, [1100], import_site=True)
         assert log.result == main(1100)
         loop, = log.loops_by_filename(self.filepath)
+        if sys.maxint > 2**32:
+            args = (63, -3689348814741910323, 3)
+        else:
+            args = (31, -858993459, 3)
         assert loop.match("""
             i11 = int_lt(i6, i7)
             guard_true(i11, descr=...)
             guard_not_invalidated(descr=...)
             i13 = int_eq(i6, %d)         # value provided below
-            i15 = int_mod(i6, 10)
-            i17 = int_rshift(i15, %d)    # value provided below
-            i18 = int_and(10, i17)
-            i19 = int_add(i15, i18)
-            i21 = int_lt(i19, 0)
-            guard_false(i21, descr=...)
-            i22 = int_ge(i19, 10)
-            guard_false(i22, descr=...)
+
+            # "mod 10" block:
+            i79 = int_rshift(i6, %d)
+            i80 = int_xor(i6, i79)
+            i82 = uint_mul_high(i80, %d)
+            i84 = uint_rshift(i82, %d)
+            i85 = int_xor(i84, i79)
+            i87 = int_mul(i85, 10)
+            i19 = int_sub(i6, i87)
+
             i23 = strgetitem(p10, i19)
             p25 = newstr(1)
             strsetitem(p25, 0, i23)
@@ -89,7 +87,7 @@
             guard_no_overflow(descr=...)
             --TICK--
             jump(..., descr=...)
-        """ % (-sys.maxint-1, SHIFT))
+        """ % ((-sys.maxint-1,)+args))
 
     def test_str_mod(self):
         def main(n):
diff --git a/pypy/objspace/std/bufferobject.py 
b/pypy/objspace/std/bufferobject.py
--- a/pypy/objspace/std/bufferobject.py
+++ b/pypy/objspace/std/bufferobject.py
@@ -135,7 +135,7 @@
         return space.wrap(rffi.cast(lltype.Signed, ptr))
 
 W_Buffer.typedef = TypeDef(
-    "buffer",
+    "buffer", None, None, "read-write",
     __doc__ = """\
 buffer(object [, offset[, size]])
 
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -848,7 +848,7 @@
 
 
 W_BytesObject.typedef = TypeDef(
-    "str", basestring_typedef,
+    "str", basestring_typedef, None, "read",
     __new__ = interp2app(W_BytesObject.descr_new),
     __doc__ = """str(object='') -> string
 
diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -7,6 +7,7 @@
 from rpython.rlib import rstring, runicode, rlocale, rfloat, jit
 from rpython.rlib.objectmodel import specialize
 from rpython.rlib.rfloat import copysign, formatd
+from rpython.rlib.rarithmetic import r_uint, intmask
 
 
 @specialize.argtype(1)
@@ -828,33 +829,37 @@
                 return s
             # This part is slow.
             negative = value < 0
-            value = abs(value)
+            base = r_uint(base)
+            value = r_uint(value)
+            if negative:   # change the sign on the unsigned number: otherwise,
+                value = -value   #   we'd risk overflow if value==-sys.maxint-1
+            #
             buf = ["\0"] * (8 * 8 + 6) # Too much on 32 bit, but who cares?
             i = len(buf) - 1
             while True:
-                div = value // base
-                mod = value - div * base
-                digit = abs(mod)
+                div = value // base         # unsigned
+                mod = value - div * base    # unsigned, always in range(0,base)
+                digit = intmask(mod)
                 digit += ord("0") if digit < 10 else ord("a") - 10
                 buf[i] = chr(digit)
-                value = div
+                value = div                 # unsigned
                 i -= 1
                 if not value:
                     break
-            if base == 2:
+            if base == r_uint(2):
                 buf[i] = "b"
                 buf[i - 1] = "0"
-            elif base == 8:
+            elif base == r_uint(8):
                 buf[i] = "o"
                 buf[i - 1] = "0"
-            elif base == 16:
+            elif base == r_uint(16):
                 buf[i] = "x"
                 buf[i - 1] = "0"
             else:
                 buf[i] = "#"
-                buf[i - 1] = chr(ord("0") + base % 10)
-                if base > 10:
-                    buf[i - 2] = chr(ord("0") + base // 10)
+                buf[i - 1] = chr(ord("0") + intmask(base % r_uint(10)))
+                if base > r_uint(10):
+                    buf[i - 2] = chr(ord("0") + intmask(base // r_uint(10)))
                     i -= 1
             i -= 1
             if negative:
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,16 +19,16 @@
 BUILDERS = [
     'own-linux-x86-32',
     'own-linux-x86-64',
-    'own-linux-armhf',
+#    'own-linux-armhf',
     'own-win-x86-32',
-    'own-linux-s390x-2',
+    'own-linux-s390x',
 #    'own-macosx-x86-32',
     'pypy-c-jit-linux-x86-32',
     'pypy-c-jit-linux-x86-64',
 #    'pypy-c-jit-freebsd-9-x86-64',
     'pypy-c-jit-macosx-x86-64',
     'pypy-c-jit-win-x86-32',
-    'pypy-c-jit-linux-s390x-2',
+    'pypy-c-jit-linux-s390x',
     'build-pypy-c-jit-linux-armhf-raring',
     'build-pypy-c-jit-linux-armhf-raspbian',
     'build-pypy-c-jit-linux-armel',
diff --git a/rpython/config/translationoption.py 
b/rpython/config/translationoption.py
--- a/rpython/config/translationoption.py
+++ b/rpython/config/translationoption.py
@@ -213,11 +213,6 @@
                    default=False),
         BoolOption("merge_if_blocks", "Merge if ... elif chains",
                    cmdline="--if-block-merge", default=True),
-        BoolOption("raisingop2direct_call",
-                   "Transform operations that can implicitly raise an "
-                   "exception into calls to functions that explicitly "
-                   "raise exceptions",
-                   default=False, cmdline="--raisingop2direct_call"),
         BoolOption("mallocs", "Remove mallocs", default=True),
         BoolOption("constfold", "Constant propagation",
                    default=True),
diff --git a/rpython/jit/backend/arm/codebuilder.py 
b/rpython/jit/backend/arm/codebuilder.py
--- a/rpython/jit/backend/arm/codebuilder.py
+++ b/rpython/jit/backend/arm/codebuilder.py
@@ -1,6 +1,5 @@
 from rpython.jit.backend.arm import conditions as cond
 from rpython.jit.backend.arm import registers as reg
-from rpython.jit.backend.arm import support
 from rpython.jit.backend.arm.arch import WORD, PC_OFFSET
 from rpython.jit.backend.arm.instruction_builder import define_instructions
 from rpython.jit.backend.llsupport.asmmemmgr import BlockBuilderMixin
@@ -17,17 +16,6 @@
     sandboxsafe=True)
 
 
-def binary_helper_call(name):
-    function = getattr(support, 'arm_%s' % name)
-
-    def f(self, c=cond.AL):
-        """Generates a call to a helper function, takes its
-        arguments in r0 and r1, result is placed in r0"""
-        addr = rffi.cast(lltype.Signed, function)
-        self.BL(addr, c)
-    return f
-
-
 class AbstractARMBuilder(object):
     def __init__(self, arch_version=7):
         self.arch_version = arch_version
@@ -348,10 +336,6 @@
         self.write32(c << 28
                     | 0x157ff05f)
 
-    DIV = binary_helper_call('int_div')
-    MOD = binary_helper_call('int_mod')
-    UDIV = binary_helper_call('uint_div')
-
     FMDRR = VMOV_cr     # uh, there are synonyms?
     FMRRD = VMOV_rc
 
diff --git a/rpython/jit/backend/arm/helper/assembler.py 
b/rpython/jit/backend/arm/helper/assembler.py
--- a/rpython/jit/backend/arm/helper/assembler.py
+++ b/rpython/jit/backend/arm/helper/assembler.py
@@ -46,20 +46,6 @@
     f.__name__ = 'emit_op_%s' % name
     return f
 
-def gen_emit_op_by_helper_call(name, opname):
-    helper = getattr(InstrBuilder, opname)
-    def f(self, op, arglocs, regalloc, fcond):
-        assert fcond is not None
-        if op.type != 'v':
-            regs = r.caller_resp[1:] + [r.ip]
-        else:
-            regs = r.caller_resp
-        with saved_registers(self.mc, regs, r.caller_vfp_resp):
-            helper(self.mc, fcond)
-        return fcond
-    f.__name__ = 'emit_op_%s' % name
-    return f
-
 def gen_emit_cmp_op(name, true_cond):
     def f(self, op, arglocs, regalloc, fcond):
         l0, l1, res = arglocs
diff --git a/rpython/jit/backend/arm/helper/regalloc.py 
b/rpython/jit/backend/arm/helper/regalloc.py
--- a/rpython/jit/backend/arm/helper/regalloc.py
+++ b/rpython/jit/backend/arm/helper/regalloc.py
@@ -72,25 +72,6 @@
     res = self.force_allocate_reg_or_cc(op)
     return [loc1, loc2, res]
 
-def prepare_op_by_helper_call(name):
-    def f(self, op, fcond):
-        assert fcond is not None
-        a0 = op.getarg(0)
-        a1 = op.getarg(1)
-        arg1 = self.rm.make_sure_var_in_reg(a0, selected_reg=r.r0)
-        arg2 = self.rm.make_sure_var_in_reg(a1, selected_reg=r.r1)
-        assert arg1 == r.r0
-        assert arg2 == r.r1
-        if not isinstance(a0, Const) and self.stays_alive(a0):
-            self.force_spill_var(a0)
-        self.possibly_free_vars_for_op(op)
-        self.free_temp_vars()
-        self.after_call(op)
-        self.possibly_free_var(op)
-        return []
-    f.__name__ = name
-    return f
-
 def prepare_int_cmp(self, op, fcond):
     assert fcond is not None
     boxes = list(op.getarglist())
diff --git a/rpython/jit/backend/arm/opassembler.py 
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -3,7 +3,7 @@
 from rpython.jit.backend.arm import registers as r
 from rpython.jit.backend.arm import shift
 from rpython.jit.backend.arm.arch import WORD, DOUBLE_WORD, JITFRAME_FIXED_SIZE
-from rpython.jit.backend.arm.helper.assembler import 
(gen_emit_op_by_helper_call,
+from rpython.jit.backend.arm.helper.assembler import (
                                                 gen_emit_op_unary_cmp,
                                                 gen_emit_op_ri,
                                                 gen_emit_cmp_op,
@@ -92,6 +92,11 @@
         self.mc.MUL(res.value, reg1.value, reg2.value)
         return fcond
 
+    def emit_op_uint_mul_high(self, op, arglocs, regalloc, fcond):
+        reg1, reg2, res = arglocs
+        self.mc.UMULL(r.ip.value, res.value, reg1.value, reg2.value)
+        return fcond
+
     def emit_op_int_force_ge_zero(self, op, arglocs, regalloc, fcond):
         arg, res = arglocs
         self.mc.CMP_ri(arg.value, 0)
@@ -132,10 +137,6 @@
         self.guard_success_cc = c.VC
         return fcond
 
-    emit_op_int_floordiv = gen_emit_op_by_helper_call('int_floordiv', 'DIV')
-    emit_op_int_mod = gen_emit_op_by_helper_call('int_mod', 'MOD')
-    emit_op_uint_floordiv = gen_emit_op_by_helper_call('uint_floordiv', 'UDIV')
-
     emit_op_int_and = gen_emit_op_ri('int_and', 'AND')
     emit_op_int_or = gen_emit_op_ri('int_or', 'ORR')
     emit_op_int_xor = gen_emit_op_ri('int_xor', 'EOR')
diff --git a/rpython/jit/backend/arm/regalloc.py 
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -7,7 +7,7 @@
 from rpython.jit.backend.arm import conditions as c
 from rpython.jit.backend.arm import locations
 from rpython.jit.backend.arm.locations import imm, get_fp_offset
-from rpython.jit.backend.arm.helper.regalloc import (prepare_op_by_helper_call,
+from rpython.jit.backend.arm.helper.regalloc import (
                                                     prepare_unary_cmp,
                                                     prepare_op_ri,
                                                     prepare_int_cmp,
@@ -467,6 +467,8 @@
         self.possibly_free_var(op)
         return [reg1, reg2, res]
 
+    prepare_op_uint_mul_high = prepare_op_int_mul
+
     def prepare_op_int_force_ge_zero(self, op, fcond):
         argloc = self.make_sure_var_in_reg(op.getarg(0))
         resloc = self.force_allocate_reg(op, [op.getarg(0)])
@@ -478,10 +480,6 @@
         resloc = self.force_allocate_reg(op)
         return [argloc, imm(numbytes), resloc]
 
-    prepare_op_int_floordiv = prepare_op_by_helper_call('int_floordiv')
-    prepare_op_int_mod = prepare_op_by_helper_call('int_mod')
-    prepare_op_uint_floordiv = prepare_op_by_helper_call('unit_floordiv')
-
     prepare_op_int_and = prepare_op_ri('int_and')
     prepare_op_int_or = prepare_op_ri('int_or')
     prepare_op_int_xor = prepare_op_ri('int_xor')
diff --git a/rpython/jit/backend/arm/support.py 
b/rpython/jit/backend/arm/support.py
deleted file mode 100644
--- a/rpython/jit/backend/arm/support.py
+++ /dev/null
@@ -1,54 +0,0 @@
-from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
-from rpython.rlib.rarithmetic import r_uint
-from rpython.translator.tool.cbuild import ExternalCompilationInfo
-
-eci = ExternalCompilationInfo(post_include_bits=["""
-static int pypy__arm_int_div(int a, int b) {
-    return a/b;
-}
-static unsigned int pypy__arm_uint_div(unsigned int a, unsigned int b) {
-    return a/b;
-}
-static int pypy__arm_int_mod(int a, int b) {
-    return a % b;
-}
-"""])
-
-
-def arm_int_div_emulator(a, b):
-    return int(a / float(b))
-arm_int_div_sign = lltype.Ptr(
-        lltype.FuncType([lltype.Signed, lltype.Signed], lltype.Signed))
-arm_int_div = rffi.llexternal(
-    "pypy__arm_int_div", [lltype.Signed, lltype.Signed], lltype.Signed,
-                        _callable=arm_int_div_emulator,
-                        compilation_info=eci,
-                        _nowrapper=True, elidable_function=True)
-
-
-def arm_uint_div_emulator(a, b):
-    return r_uint(a) / r_uint(b)
-arm_uint_div_sign = lltype.Ptr(
-        lltype.FuncType([lltype.Unsigned, lltype.Unsigned], lltype.Unsigned))
-arm_uint_div = rffi.llexternal(
-    "pypy__arm_uint_div", [lltype.Unsigned, lltype.Unsigned], lltype.Unsigned,
-                        _callable=arm_uint_div_emulator,
-                        compilation_info=eci,
-                        _nowrapper=True, elidable_function=True)
-
-
-def arm_int_mod_emulator(a, b):
-    sign = 1
-    if a < 0:
-        a = -1 * a
-        sign = -1
-    if b < 0:
-        b = -1 * b
-    res = a % b
-    return sign * res
-arm_int_mod_sign = arm_int_div_sign
-arm_int_mod = rffi.llexternal(
-    "pypy__arm_int_mod", [lltype.Signed, lltype.Signed], lltype.Signed,
-                        _callable=arm_int_mod_emulator,
-                        compilation_info=eci,
-                        _nowrapper=True, elidable_function=True)
diff --git a/rpython/jit/backend/arm/test/test_arch.py 
b/rpython/jit/backend/arm/test/test_arch.py
deleted file mode 100644
--- a/rpython/jit/backend/arm/test/test_arch.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from rpython.jit.backend.arm import support
-
-def test_mod():
-    assert support.arm_int_mod(10, 2) == 0
-    assert support.arm_int_mod(11, 2) == 1
-    assert support.arm_int_mod(11, 3) == 2
-
-def test_mod2():
-    assert support.arm_int_mod(-10, 2) == 0
-    assert support.arm_int_mod(-11, 2) == -1
-    assert support.arm_int_mod(-11, 3) == -2
-
-def test_mod3():
-    assert support.arm_int_mod(10, -2) == 0
-    assert support.arm_int_mod(11, -2) == 1
-    assert support.arm_int_mod(11, -3) == 2
-
-
-def test_div():
-    assert support.arm_int_div(-7, 2) == -3
-    assert support.arm_int_div(9, 2) == 4
-    assert support.arm_int_div(10, 5) == 2
-
diff --git a/rpython/jit/backend/arm/test/test_assembler.py 
b/rpython/jit/backend/arm/test/test_assembler.py
--- a/rpython/jit/backend/arm/test/test_assembler.py
+++ b/rpython/jit/backend/arm/test/test_assembler.py
@@ -193,32 +193,6 @@
         self.a.gen_func_epilog()
         assert run_asm(self.a) == 61
 
-    def test_DIV(self):
-        self.a.gen_func_prolog()
-        self.a.mc.MOV_ri(r.r0.value, 123)
-        self.a.mc.MOV_ri(r.r1.value, 2)
-        self.a.mc.DIV()
-        self.a.gen_func_epilog()
-        assert run_asm(self.a) == 61
-
-    def test_DIV2(self):
-        self.a.gen_func_prolog()
-        self.a.mc.gen_load_int(r.r0.value, -110)
-        self.a.mc.gen_load_int(r.r1.value, 3)
-        self.a.mc.DIV()
-        self.a.gen_func_epilog()
-        assert run_asm(self.a) == -36
-
-    def test_DIV3(self):
-        self.a.gen_func_prolog()
-        self.a.mc.gen_load_int(r.r8.value, 110)
-        self.a.mc.gen_load_int(r.r9.value, -3)
-        self.a.mc.MOV_rr(r.r0.value, r.r8.value)
-        self.a.mc.MOV_rr(r.r1.value, r.r9.value)
-        self.a.mc.DIV()
-        self.a.gen_func_epilog()
-        assert run_asm(self.a) == -36
-
     def test_bl_with_conditional_exec(self):
         functype = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed))
         call_addr = rffi.cast(lltype.Signed, llhelper(functype, callme))
diff --git a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py 
b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_regalloc_integration.py
@@ -496,22 +496,6 @@
         self.interpret(ops, [s, ord('a')])
         assert s[1] == 'a'
 
-    def test_division_optimized(self):
-        ops = '''
-        [i7, i6]
-        label(i7, i6, descr=targettoken)
-        i18 = int_floordiv(i7, i6)
-        i19 = int_xor(i7, i6)
-        i21 = int_lt(i19, 0)
-        i22 = int_mod(i7, i6)
-        i23 = int_is_true(i22)
-        i24 = int_eq(i6, 4)
-        guard_false(i24) [i18]
-        jump(i18, i6, descr=targettoken)
-        '''
-        self.interpret(ops, [10, 4])
-        assert self.getint(0) == 2
-        # FIXME: Verify that i19 - i23 are removed
 
 class TestRegallocFloats(BaseTestRegalloc):
     def setup_class(cls):
diff --git a/rpython/jit/backend/ppc/opassembler.py 
b/rpython/jit/backend/ppc/opassembler.py
--- a/rpython/jit/backend/ppc/opassembler.py
+++ b/rpython/jit/backend/ppc/opassembler.py
@@ -62,6 +62,12 @@
         else:
             self.mc.mulld(res.value, l0.value, l1.value)
 
+    def emit_uint_mul_high(self, op, arglocs, regalloc):
+        l0, l1, res = arglocs
+        assert not l0.is_imm()
+        assert not l1.is_imm()
+        self.mc.mulhdu(res.value, l0.value, l1.value)
+
     def do_emit_int_binary_ovf(self, op, arglocs):
         l0, l1, res = arglocs[0], arglocs[1], arglocs[2]
         self.mc.load_imm(r.SCRATCH, 0)
@@ -80,24 +86,6 @@
         else:
             self.mc.mulldox(*self.do_emit_int_binary_ovf(op, arglocs))
 
-    def emit_int_floordiv(self, op, arglocs, regalloc):
-        l0, l1, res = arglocs
-        if IS_PPC_32:
-            self.mc.divw(res.value, l0.value, l1.value)
-        else:
-            self.mc.divd(res.value, l0.value, l1.value)
-
-    def emit_int_mod(self, op, arglocs, regalloc):
-        l0, l1, res = arglocs
-        if IS_PPC_32:
-            self.mc.divw(r.r0.value, l0.value, l1.value)
-            self.mc.mullw(r.r0.value, r.r0.value, l1.value)
-        else:
-            self.mc.divd(r.r0.value, l0.value, l1.value)
-            self.mc.mulld(r.r0.value, r.r0.value, l1.value)
-        self.mc.subf(r.r0.value, r.r0.value, l0.value)
-        self.mc.mr(res.value, r.r0.value)
-
     def emit_int_and(self, op, arglocs, regalloc):
         l0, l1, res = arglocs
         self.mc.and_(res.value, l0.value, l1.value)
@@ -130,13 +118,6 @@
             self.mc.srw(res.value, l0.value, l1.value)
         else:
             self.mc.srd(res.value, l0.value, l1.value)
-    
-    def emit_uint_floordiv(self, op, arglocs, regalloc):
-        l0, l1, res = arglocs
-        if IS_PPC_32:
-            self.mc.divwu(res.value, l0.value, l1.value)
-        else:
-            self.mc.divdu(res.value, l0.value, l1.value)
 
     emit_int_le = gen_emit_cmp_op(c.LE)
     emit_int_lt = gen_emit_cmp_op(c.LT)
diff --git a/rpython/jit/backend/ppc/regalloc.py 
b/rpython/jit/backend/ppc/regalloc.py
--- a/rpython/jit/backend/ppc/regalloc.py
+++ b/rpython/jit/backend/ppc/regalloc.py
@@ -432,15 +432,13 @@
     prepare_int_mul = helper.prepare_int_add_or_mul
     prepare_nursery_ptr_increment = prepare_int_add
 
-    prepare_int_floordiv = helper.prepare_binary_op
-    prepare_int_mod = helper.prepare_binary_op
     prepare_int_and = helper.prepare_binary_op
     prepare_int_or = helper.prepare_binary_op
     prepare_int_xor = helper.prepare_binary_op
     prepare_int_lshift = helper.prepare_binary_op
     prepare_int_rshift = helper.prepare_binary_op
     prepare_uint_rshift = helper.prepare_binary_op
-    prepare_uint_floordiv = helper.prepare_binary_op
+    prepare_uint_mul_high = helper.prepare_binary_op
 
     prepare_int_add_ovf = helper.prepare_binary_op
     prepare_int_sub_ovf = helper.prepare_binary_op
diff --git a/rpython/jit/backend/test/test_random.py 
b/rpython/jit/backend/test/test_random.py
--- a/rpython/jit/backend/test/test_random.py
+++ b/rpython/jit/backend/test/test_random.py
@@ -532,6 +532,7 @@
             rop.INT_AND,
             rop.INT_OR,
             rop.INT_XOR,
+            rop.UINT_MUL_HIGH,
             ]:
     OPERATIONS.append(BinaryOperation(_op))
 
@@ -548,8 +549,8 @@
             ]:
     OPERATIONS.append(BinaryOperation(_op, boolres=True))
 
-OPERATIONS.append(BinaryOperation(rop.INT_FLOORDIV, ~3, 2))
-OPERATIONS.append(BinaryOperation(rop.INT_MOD, ~3, 2))
+#OPERATIONS.append(BinaryOperation(rop.INT_FLOORDIV, ~3, 2))
+#OPERATIONS.append(BinaryOperation(rop.INT_MOD, ~3, 2))
 OPERATIONS.append(BinaryOperation(rop.INT_RSHIFT, LONG_BIT-1))
 OPERATIONS.append(BinaryOperation(rop.INT_LSHIFT, LONG_BIT-1))
 OPERATIONS.append(BinaryOperation(rop.UINT_RSHIFT, LONG_BIT-1))
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
@@ -1289,6 +1289,9 @@
     genop_float_mul = _binaryop('MULSD')
     genop_float_truediv = _binaryop('DIVSD')
 
+    def genop_uint_mul_high(self, op, arglocs, result_loc):
+        self.mc.MUL(arglocs[0])
+
     def genop_int_and(self, op, arglocs, result_loc):
         arg1 = arglocs[1]
         if IS_X86_64 and (isinstance(arg1, ImmedLoc) and
@@ -1444,20 +1447,6 @@
         self.mov(imm0, resloc)
         self.mc.CMOVNS(resloc, arglocs[0])
 
-    def genop_int_mod(self, op, arglocs, resloc):
-        if IS_X86_32:
-            self.mc.CDQ()
-        elif IS_X86_64:
-            self.mc.CQO()
-
-        self.mc.IDIV_r(ecx.value)
-
-    genop_int_floordiv = genop_int_mod
-
-    def genop_uint_floordiv(self, op, arglocs, resloc):
-        self.mc.XOR_rr(edx.value, edx.value)
-        self.mc.DIV_r(ecx.value)
-
     genop_llong_add = _binaryop("PADDQ")
     genop_llong_sub = _binaryop("PSUBQ")
     genop_llong_and = _binaryop("PAND")
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
@@ -561,6 +561,27 @@
     consider_int_sub_ovf = _consider_binop
     consider_int_add_ovf = _consider_binop_symm
 
+    def consider_uint_mul_high(self, op):
+        arg1, arg2 = op.getarglist()
+        # should support all cases, but is optimized for (box, const)
+        if isinstance(arg1, Const):
+            arg1, arg2 = arg2, arg1
+        self.rm.make_sure_var_in_reg(arg2, selected_reg=eax)
+        l1 = self.loc(arg1)
+        # l1 is a register != eax, or stack_bp; or, just possibly, it
+        # can be == eax if arg1 is arg2
+        assert not isinstance(l1, ImmedLoc)
+        assert l1 is not eax or arg1 is arg2
+        #
+        # eax will be trash after the operation
+        self.rm.possibly_free_var(arg2)
+        tmpvar = TempVar()
+        self.rm.force_allocate_reg(tmpvar, selected_reg=eax)
+        self.rm.possibly_free_var(tmpvar)
+        #
+        self.rm.force_allocate_reg(op, selected_reg=edx)
+        self.perform(op, [l1], edx)
+
     def consider_int_neg(self, op):
         res = self.rm.force_result_in_reg(op, op.getarg(0))
         self.perform(op, [res], res)
@@ -585,29 +606,6 @@
     consider_int_rshift  = consider_int_lshift
     consider_uint_rshift = consider_int_lshift
 
-    def _consider_int_div_or_mod(self, op, resultreg, trashreg):
-        l0 = self.rm.make_sure_var_in_reg(op.getarg(0), selected_reg=eax)
-        l1 = self.rm.make_sure_var_in_reg(op.getarg(1), selected_reg=ecx)
-        l2 = self.rm.force_allocate_reg(op, selected_reg=resultreg)
-        # the register (eax or edx) not holding what we are looking for
-        # will be just trash after that operation
-        tmpvar = TempVar()
-        self.rm.force_allocate_reg(tmpvar, selected_reg=trashreg)
-        assert l0 is eax
-        assert l1 is ecx
-        assert l2 is resultreg
-        self.rm.possibly_free_var(tmpvar)
-
-    def consider_int_mod(self, op):
-        self._consider_int_div_or_mod(op, edx, eax)
-        self.perform(op, [eax, ecx], edx)
-
-    def consider_int_floordiv(self, op):
-        self._consider_int_div_or_mod(op, eax, edx)
-        self.perform(op, [eax, ecx], eax)
-
-    consider_uint_floordiv = consider_int_floordiv
-
     def _consider_compop(self, op):
         vx = op.getarg(0)
         vy = op.getarg(1)
diff --git a/rpython/jit/backend/x86/regloc.py 
b/rpython/jit/backend/x86/regloc.py
--- a/rpython/jit/backend/x86/regloc.py
+++ b/rpython/jit/backend/x86/regloc.py
@@ -641,6 +641,7 @@
     SUB = _binaryop('SUB')
     IMUL = _binaryop('IMUL')
     NEG = _unaryop('NEG')
+    MUL = _unaryop('MUL')
 
     CMP = _binaryop('CMP')
     CMP16 = _binaryop('CMP16')
diff --git a/rpython/jit/backend/x86/rx86.py b/rpython/jit/backend/x86/rx86.py
--- a/rpython/jit/backend/x86/rx86.py
+++ b/rpython/jit/backend/x86/rx86.py
@@ -558,6 +558,9 @@
     DIV_r = insn(rex_w, '\xF7', register(1), '\xF0')
     IDIV_r = insn(rex_w, '\xF7', register(1), '\xF8')
 
+    MUL_r = insn(rex_w, '\xF7', orbyte(4<<3), register(1), '\xC0')
+    MUL_b = insn(rex_w, '\xF7', orbyte(4<<3), stack_bp(1))
+
     IMUL_rr = insn(rex_w, '\x0F\xAF', register(1, 8), register(2), '\xC0')
     IMUL_rb = insn(rex_w, '\x0F\xAF', register(1, 8), stack_bp(2))
 
diff --git a/rpython/jit/codewriter/effectinfo.py 
b/rpython/jit/codewriter/effectinfo.py
--- a/rpython/jit/codewriter/effectinfo.py
+++ b/rpython/jit/codewriter/effectinfo.py
@@ -28,6 +28,11 @@
     OS_THREADLOCALREF_GET       = 5    # llop.threadlocalref_get
     OS_NOT_IN_TRACE             = 8    # for calls not recorded in the jit 
trace
     #
+    OS_INT_PY_DIV               = 12   # python signed division (neg. 
corrected)
+    OS_INT_UDIV                 = 13   # regular unsigned division
+    OS_INT_PY_MOD               = 14   # python signed modulo (neg. corrected)
+    OS_INT_UMOD                 = 15   # regular unsigned modulo
+    #
     OS_STR_CONCAT               = 22   # "stroruni.concat"
     OS_STR_SLICE                = 23   # "stroruni.slice"
     OS_STR_EQUAL                = 24   # "stroruni.equal"
diff --git a/rpython/jit/codewriter/jtransform.py 
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -436,6 +436,8 @@
         # dispatch to various implementations depending on the oopspec_name
         if oopspec_name.startswith('list.') or 
oopspec_name.startswith('newlist'):
             prepare = self._handle_list_call
+        elif oopspec_name.startswith('int.'):
+            prepare = self._handle_int_special
         elif oopspec_name.startswith('stroruni.'):
             prepare = self._handle_stroruni_call
         elif oopspec_name == 'str.str2unicode':
@@ -518,23 +520,12 @@
 
     # XXX some of the following functions should not become residual calls
     # but be really compiled
-    rewrite_op_int_floordiv_ovf_zer   = _do_builtin_call
-    rewrite_op_int_floordiv_ovf       = _do_builtin_call
-    rewrite_op_int_floordiv_zer       = _do_builtin_call
-    rewrite_op_int_mod_ovf_zer        = _do_builtin_call
-    rewrite_op_int_mod_ovf            = _do_builtin_call
-    rewrite_op_int_mod_zer            = _do_builtin_call
-    rewrite_op_int_lshift_ovf         = _do_builtin_call
     rewrite_op_int_abs                = _do_builtin_call
     rewrite_op_llong_abs              = _do_builtin_call
     rewrite_op_llong_floordiv         = _do_builtin_call
-    rewrite_op_llong_floordiv_zer     = _do_builtin_call
     rewrite_op_llong_mod              = _do_builtin_call
-    rewrite_op_llong_mod_zer          = _do_builtin_call
     rewrite_op_ullong_floordiv        = _do_builtin_call
-    rewrite_op_ullong_floordiv_zer    = _do_builtin_call
     rewrite_op_ullong_mod             = _do_builtin_call
-    rewrite_op_ullong_mod_zer         = _do_builtin_call
     rewrite_op_gc_identityhash        = _do_builtin_call
     rewrite_op_gc_id                  = _do_builtin_call
     rewrite_op_gc_pin                 = _do_builtin_call
@@ -1532,12 +1523,6 @@
                 return self.rewrite_operation(op1)
         ''' % (_old, _new)).compile()
 
-    def rewrite_op_int_neg_ovf(self, op):
-        op1 = SpaceOperation('int_sub_ovf',
-                             [Constant(0, lltype.Signed), op.args[0]],
-                             op.result)
-        return self.rewrite_operation(op1)
-
     def rewrite_op_float_is_true(self, op):
         op1 = SpaceOperation('float_ne',
                              [op.args[0], Constant(0.0, lltype.Float)],
@@ -1929,6 +1914,20 @@
                 llmemory.cast_ptr_to_adr(c_func.value))
         self.callcontrol.callinfocollection.add(oopspecindex, calldescr, func)
 
+    def _handle_int_special(self, op, oopspec_name, args):
+        if oopspec_name == 'int.neg_ovf':
+            [v_x] = args
+            op0 = SpaceOperation('int_sub_ovf',
+                                 [Constant(0, lltype.Signed), v_x],
+                                 op.result)
+            return self.rewrite_operation(op0)
+        else:
+            # int.py_div, int.udiv, int.py_mod, int.umod
+            opname = oopspec_name.replace('.', '_')
+            os = getattr(EffectInfo, 'OS_' + opname.upper())
+            return self._handle_oopspec_call(op, args, os,
+                                    EffectInfo.EF_ELIDABLE_CANNOT_RAISE)
+
     def _handle_stroruni_call(self, op, oopspec_name, args):
         SoU = args[0].concretetype     # Ptr(STR) or Ptr(UNICODE)
         can_raise_memoryerror = {
diff --git a/rpython/jit/codewriter/support.py 
b/rpython/jit/codewriter/support.py
--- a/rpython/jit/codewriter/support.py
+++ b/rpython/jit/codewriter/support.py
@@ -243,45 +243,6 @@
     return llop.jit_force_virtual(lltype.typeOf(inst), inst)
 
 
-def _ll_2_int_floordiv_ovf_zer(x, y):
-    if y == 0:
-        raise ZeroDivisionError
-    return _ll_2_int_floordiv_ovf(x, y)
-
-def _ll_2_int_floordiv_ovf(x, y):
-    # intentionally not short-circuited to produce only one guard
-    # and to remove the check fully if one of the arguments is known
-    if (x == -sys.maxint - 1) & (y == -1):
-        raise OverflowError
-    return llop.int_floordiv(lltype.Signed, x, y)
-
-def _ll_2_int_floordiv_zer(x, y):
-    if y == 0:
-        raise ZeroDivisionError
-    return llop.int_floordiv(lltype.Signed, x, y)
-
-def _ll_2_int_mod_ovf_zer(x, y):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to