[pypy-commit] pypy default: merged upstream

alex_gaynor noreply at buildbot.pypy.org
Tue Jun 4 06:42:59 CEST 2013


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: 
Changeset: r64746:dd7556ff00b9
Date: 2013-06-03 23:42 -0500
http://bitbucket.org/pypy/pypy/changeset/dd7556ff00b9/

Log:	merged upstream

diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py
--- a/lib-python/2.7/distutils/command/build_ext.py
+++ b/lib-python/2.7/distutils/command/build_ext.py
@@ -8,7 +8,7 @@
 
 __revision__ = "$Id$"
 
-import sys, os, string, re
+import sys, os, string, re, imp
 from types import *
 from site import USER_BASE, USER_SITE
 from distutils.core import Command
@@ -33,6 +33,11 @@
     from distutils.ccompiler import show_compilers
     show_compilers()
 
+def _get_c_extension_suffix():
+    for ext, mod, typ in imp.get_suffixes():
+        if typ == imp.C_EXTENSION:
+            return ext
+
 
 class build_ext (Command):
 
@@ -677,10 +682,18 @@
         # OS/2 has an 8 character module (extension) limit :-(
         if os.name == "os2":
             ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8]
+        # PyPy tweak: first try to get the C extension suffix from
+        # 'imp'.  If it fails we fall back to the 'SO' config var, like
+        # the previous version of this code did.  This should work for
+        # CPython too.  The point is that on PyPy with cpyext, the
+        # config var 'SO' is just ".so" but we want to return
+        # ".pypy-VERSION.so" instead.
+        so_ext = _get_c_extension_suffix()
+        if so_ext is None:
+            so_ext = get_config_var('SO')     # fall-back
         # extensions in debug_mode are named 'module_d.pyd' under windows
-        so_ext = get_config_var('SO')
         if os.name == 'nt' and self.debug:
-            return os.path.join(*ext_path) + '_d' + so_ext
+            so_ext = '_d.pyd'
         return os.path.join(*ext_path) + so_ext
 
     def get_export_symbols (self, ext):
diff --git a/lib-python/2.7/distutils/sysconfig_pypy.py b/lib-python/2.7/distutils/sysconfig_pypy.py
--- a/lib-python/2.7/distutils/sysconfig_pypy.py
+++ b/lib-python/2.7/distutils/sysconfig_pypy.py
@@ -12,7 +12,6 @@
 
 import sys
 import os
-import imp
 
 from distutils.errors import DistutilsPlatformError
 
@@ -58,16 +57,11 @@
 
 _config_vars = None
 
-def _get_so_extension():
-    for ext, mod, typ in imp.get_suffixes():
-        if typ == imp.C_EXTENSION:
-            return ext
-
 def _init_posix():
     """Initialize the module as appropriate for POSIX systems."""
     g = {}
     g['EXE'] = ""
-    g['SO'] = _get_so_extension() or ".so"
+    g['SO'] = ".so"
     g['SOABI'] = g['SO'].rsplit('.')[0]
     g['LIBDIR'] = os.path.join(sys.prefix, 'lib')
     g['CC'] = "gcc -pthread" # -pthread might not be valid on OS/X, check
@@ -80,7 +74,7 @@
     """Initialize the module as appropriate for NT"""
     g = {}
     g['EXE'] = ".exe"
-    g['SO'] = _get_so_extension() or ".pyd"
+    g['SO'] = ".pyd"
     g['SOABI'] = g['SO'].rsplit('.')[0]
 
     global _config_vars
diff --git a/lib-python/2.7/logging/__init__.py b/lib-python/2.7/logging/__init__.py
--- a/lib-python/2.7/logging/__init__.py
+++ b/lib-python/2.7/logging/__init__.py
@@ -151,6 +151,8 @@
     'DEBUG': DEBUG,
     'NOTSET': NOTSET,
 }
+_levelNames = dict(_levelToName)
+_levelNames.update(_nameToLevel)   # backward compatibility
 
 def getLevelName(level):
     """
diff --git a/lib_pypy/_ctypes_test.py b/lib_pypy/_ctypes_test.py
--- a/lib_pypy/_ctypes_test.py
+++ b/lib_pypy/_ctypes_test.py
@@ -1,60 +1,7 @@
-import os, sys
-import tempfile
-
-def compile_shared():
-    """Compile '_ctypes_test.c' into an extension module, and import it
-    """
-    thisdir = os.path.dirname(__file__)
-    output_dir = tempfile.mkdtemp()
-
-    from distutils.ccompiler import new_compiler
-    from distutils import sysconfig
-
-    compiler = new_compiler()
-    compiler.output_dir = output_dir
-
-    # Compile .c file
-    include_dir = os.path.join(thisdir, '..', 'include')
-    if sys.platform == 'win32':
-        ccflags = ['-D_CRT_SECURE_NO_WARNINGS']
-    else:
-        ccflags = ['-fPIC', '-Wimplicit-function-declaration']
-    res = compiler.compile([os.path.join(thisdir, '_ctypes_test.c')],
-                           include_dirs=[include_dir],
-                           extra_preargs=ccflags)
-    object_filename = res[0]
-
-    # set link options
-    output_filename = '_ctypes_test' + sysconfig.get_config_var('SO')
-    if sys.platform == 'win32':
-        # XXX libpypy-c.lib is currently not installed automatically
-        library = os.path.join(thisdir, '..', 'include', 'libpypy-c')
-        if not os.path.exists(library + '.lib'):
-            #For a nightly build
-            library = os.path.join(thisdir, '..', 'include', 'python27')
-        if not os.path.exists(library + '.lib'):
-            # For a local translation
-            library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c')
-        libraries = [library, 'oleaut32']
-        extra_ldargs = ['/MANIFEST',  # needed for VC10
-                        '/EXPORT:init_ctypes_test']
-    else:
-        libraries = []
-        extra_ldargs = []
-
-    # link the dynamic library
-    compiler.link_shared_object(
-        [object_filename],
-        output_filename,
-        libraries=libraries,
-        extra_preargs=extra_ldargs)
-
-    # Now import the newly created library, it will replace our module in sys.modules
-    import imp
-    fp, filename, description = imp.find_module('_ctypes_test', path=[output_dir])
-    imp.load_module('_ctypes_test', fp, filename, description)
-
-
+try:
+    import cpyext
+except ImportError:
+    raise ImportError("No module named '_ctypes_test'")
 try:
     import _ctypes
     _ctypes.PyObj_FromPtr = None
@@ -62,4 +9,5 @@
 except ImportError:
     pass    # obscure condition of _ctypes_test.py being imported by py.test
 else:
-    compile_shared()
+    import _pypy_testcapi
+    _pypy_testcapi.compile_shared('_ctypes_test.c', '_ctypes_test')
diff --git a/lib_pypy/_pypy_testcapi.py b/lib_pypy/_pypy_testcapi.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/_pypy_testcapi.py
@@ -0,0 +1,61 @@
+import os, sys, imp
+import tempfile
+
+def _get_c_extension_suffix():
+    for ext, mod, typ in imp.get_suffixes():
+        if typ == imp.C_EXTENSION:
+            return ext
+
+
+def compile_shared(csource, modulename):
+    """Compile '_testcapi.c' or '_ctypes_test.c' into an extension module,
+    and import it.
+    """
+    thisdir = os.path.dirname(__file__)
+    output_dir = tempfile.mkdtemp()
+
+    from distutils.ccompiler import new_compiler
+
+    compiler = new_compiler()
+    compiler.output_dir = output_dir
+
+    # Compile .c file
+    include_dir = os.path.join(thisdir, '..', 'include')
+    if sys.platform == 'win32':
+        ccflags = ['-D_CRT_SECURE_NO_WARNINGS']
+    else:
+        ccflags = ['-fPIC', '-Wimplicit-function-declaration']
+    res = compiler.compile([os.path.join(thisdir, csource)],
+                           include_dirs=[include_dir],
+                           extra_preargs=ccflags)
+    object_filename = res[0]
+
+    # set link options
+    output_filename = modulename + _get_c_extension_suffix()
+    if sys.platform == 'win32':
+        # XXX libpypy-c.lib is currently not installed automatically
+        library = os.path.join(thisdir, '..', 'include', 'libpypy-c')
+        if not os.path.exists(library + '.lib'):
+            #For a nightly build
+            library = os.path.join(thisdir, '..', 'include', 'python27')
+        if not os.path.exists(library + '.lib'):
+            # For a local translation
+            library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c')
+        libraries = [library, 'oleaut32']
+        extra_ldargs = ['/MANIFEST',  # needed for VC10
+                        '/EXPORT:init' + modulename]
+    else:
+        libraries = []
+        extra_ldargs = []
+
+    # link the dynamic library
+    compiler.link_shared_object(
+        [object_filename],
+        output_filename,
+        libraries=libraries,
+        extra_preargs=extra_ldargs)
+
+    # Now import the newly created library, it will replace the original
+    # module in sys.modules
+    fp, filename, description = imp.find_module(modulename, path=[output_dir])
+    imp.load_module(modulename, fp, filename, description)
diff --git a/lib_pypy/_testcapi.py b/lib_pypy/_testcapi.py
--- a/lib_pypy/_testcapi.py
+++ b/lib_pypy/_testcapi.py
@@ -1,62 +1,7 @@
-import os, sys
-import tempfile
-
-def compile_shared():
-    """Compile '_testcapi.c' into an extension module, and import it
-    """
-    thisdir = os.path.dirname(__file__)
-    output_dir = tempfile.mkdtemp()
-
-    from distutils.ccompiler import new_compiler
-    from distutils import sysconfig
-
-    compiler = new_compiler()
-    compiler.output_dir = output_dir
-
-    # Compile .c file
-    include_dir = os.path.join(thisdir, '..', 'include')
-    if sys.platform == 'win32':
-        ccflags = ['-D_CRT_SECURE_NO_WARNINGS']
-    else:
-        ccflags = ['-fPIC', '-Wimplicit-function-declaration']
-    res = compiler.compile([os.path.join(thisdir, '_testcapimodule.c')],
-                           include_dirs=[include_dir],
-                           extra_preargs=ccflags)
-    object_filename = res[0]
-
-    # set link options
-    output_filename = '_testcapi' + sysconfig.get_config_var('SO')
-    if sys.platform == 'win32':
-        # XXX libpypy-c.lib is currently not installed automatically
-        library = os.path.join(thisdir, '..', 'include', 'libpypy-c')
-        if not os.path.exists(library + '.lib'):
-            #For a nightly build
-            library = os.path.join(thisdir, '..', 'include', 'python27')
-        if not os.path.exists(library + '.lib'):
-            # For a local translation
-            library = os.path.join(thisdir, '..', 'pypy', 'goal', 'libpypy-c')
-        libraries = [library, 'oleaut32']
-        extra_ldargs = ['/MANIFEST',  # needed for VC10
-                        '/EXPORT:init_testcapi']
-    else:
-        libraries = []
-        extra_ldargs = []
-
-    # link the dynamic library
-    compiler.link_shared_object(
-        [object_filename],
-        output_filename,
-        libraries=libraries,
-        extra_preargs=extra_ldargs)
-
-    # Now import the newly created library, it will replace our module in sys.modules
-    import imp
-    fp, filename, description = imp.find_module('_testcapi', path=[output_dir])
-    imp.load_module('_testcapi', fp, filename, description)
-
 try:
     import cpyext
 except ImportError:
     raise ImportError("No module named '_testcapi'")
 else:
-    compile_shared()
+    import _pypy_testcapi
+    _pypy_testcapi.compile_shared('_testcapimodule.c', '_testcapi')
diff --git a/pypy/doc/__pypy__-module.rst b/pypy/doc/__pypy__-module.rst
--- a/pypy/doc/__pypy__-module.rst
+++ b/pypy/doc/__pypy__-module.rst
@@ -1,3 +1,7 @@
+
+.. comment: this document is very incomplete, should we generate
+            it automatically?
+
 =======================
 The ``__pypy__`` module
 =======================
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
@@ -46,3 +46,7 @@
 
 .. branch: operrfmt-NT
 Adds a couple convenient format specifiers to operationerrfmt
+
+.. branch: win32-fixes3
+Skip and fix some non-translated (own) tests for win32 builds
+
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -2,7 +2,7 @@
 PyPy on Windows
 ===============
 
-Pypy is supported on Windows platforms, starting with Windows 2000.
+PyPy is supported on Windows platforms, starting with Windows 2000.
 The following text gives some hints about how to translate the PyPy
 interpreter.
 
@@ -199,9 +199,9 @@
 
 or such, depending on your mingw64 download.
 
-hacking on Pypy with the mingw compiler
+hacking on PyPy with the mingw compiler
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Since hacking on Pypy means running tests, you will need a way to specify
+Since hacking on PyPy means running tests, you will need a way to specify
 the mingw compiler when hacking (as opposed to translating). As of
 March 2012, --cc is not a valid option for pytest.py. However if you set an
 environment variable CC to the compliter exe, testing will use it.
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
@@ -578,6 +578,11 @@
 class TestNonInteractive:
     def run_with_status_code(self, cmdline, senddata='', expect_prompt=False,
             expect_banner=False, python_flags='', env=None):
+        if os.name == 'nt':
+            try:
+                import __pypy__
+            except:
+                py.test.skip('app_main cannot run on non-pypy for windows')
         cmdline = '%s %s "%s" %s' % (sys.executable, python_flags,
                                      app_main, cmdline)
         print 'POPEN:', cmdline
@@ -706,6 +711,11 @@
         assert 'copyright' not in data
 
     def test_non_interactive_stdout_fully_buffered(self):
+        if os.name == 'nt':
+            try:
+                import __pypy__
+            except:
+                py.test.skip('app_main cannot run on non-pypy for windows')
         path = getscript(r"""
             import sys, time
             sys.stdout.write('\x00(STDOUT)\n\x00')   # stays in buffers
@@ -726,6 +736,11 @@
 
     def test_non_interactive_stdout_unbuffered(self, monkeypatch):
         monkeypatch.setenv('PYTHONUNBUFFERED', '1')
+        if os.name == 'nt':
+            try:
+                import __pypy__
+            except:
+                py.test.skip('app_main cannot run on non-pypy for windows')
         path = getscript(r"""
             import sys, time
             sys.stdout.write('\x00(STDOUT)\n\x00')
diff --git a/pypy/module/_cffi_backend/newtype.py b/pypy/module/_cffi_backend/newtype.py
--- a/pypy/module/_cffi_backend/newtype.py
+++ b/pypy/module/_cffi_backend/newtype.py
@@ -1,3 +1,4 @@
+import sys
 from pypy.interpreter.error import OperationError, operationerrfmt
 from pypy.interpreter.gateway import unwrap_spec
 
@@ -113,6 +114,14 @@
 
 # ____________________________________________________________
 
+SF_MSVC_BITFIELDS = 1
+
+if sys.platform == 'win32':
+    DEFAULT_SFLAGS = SF_MSVC_BITFIELDS
+else:
+    DEFAULT_SFLAGS = 0
+
+
 @unwrap_spec(name=str)
 def new_struct_type(space, name):
     return ctypestruct.W_CTypeStruct(space, name)
@@ -121,9 +130,11 @@
 def new_union_type(space, name):
     return ctypestruct.W_CTypeUnion(space, name)
 
- at unwrap_spec(w_ctype=ctypeobj.W_CType, totalsize=int, totalalignment=int)
+ at unwrap_spec(w_ctype=ctypeobj.W_CType, totalsize=int, totalalignment=int,
+             sflags=int)
 def complete_struct_or_union(space, w_ctype, w_fields, w_ignored=None,
-                             totalsize=-1, totalalignment=-1):
+                             totalsize=-1, totalalignment=-1,
+                             sflags=DEFAULT_SFLAGS):
     if (not isinstance(w_ctype, ctypestruct.W_CTypeStructOrUnion)
             or w_ctype.size >= 0):
         raise OperationError(space.w_TypeError,
@@ -134,6 +145,8 @@
     alignment = 1
     boffset = 0         # this number is in *bits*, not bytes!
     boffsetmax = 0      # the maximum value of boffset, in bits too
+    prev_bitfield_size = 0
+    prev_bitfield_free = 0
     fields_w = space.listview(w_fields)
     fields_list = []
     fields_dict = {}
@@ -166,7 +179,15 @@
         # update the total alignment requirement, but skip it if the
         # field is an anonymous bitfield
         falign = ftype.alignof()
-        if alignment < falign and (fbitsize < 0 or fname != ''):
+        do_align = True
+        if fbitsize >= 0:
+            if (sflags & SF_MSVC_BITFIELDS) == 0:
+                # GCC: anonymous bitfields (of any size) don't cause alignment
+                do_align = (fname != '')
+            else:
+                # MSVC: zero-sized bitfields don't cause alignment
+                do_align = (fbitsize > 0)
+        if alignment < falign and do_align:
             alignment = falign
         #
         if fbitsize < 0:
@@ -208,6 +229,7 @@
                 fields_dict[fname] = fld
 
             boffset += ftype.size * 8
+            prev_bitfield_size = 0
 
         else:
             # this is the case of a bitfield
@@ -243,31 +265,67 @@
                     raise operationerrfmt(space.w_TypeError,
                                           "field '%s.%s' is declared with :0",
                                           w_ctype.name, fname)
-                if boffset > field_offset_bytes * 8:
-                    field_offset_bytes += falign
-                    assert boffset < field_offset_bytes * 8
-                boffset = field_offset_bytes * 8
+                if (sflags & SF_MSVC_BITFIELDS) == 0:
+                    # GCC's notion of "ftype :0;"
+                    # pad boffset to a value aligned for "ftype"
+                    if boffset > field_offset_bytes * 8:
+                        field_offset_bytes += falign
+                        assert boffset < field_offset_bytes * 8
+                    boffset = field_offset_bytes * 8
+                else:
+                    # MSVC's notion of "ftype :0;
+                    # Mostly ignored.  It seems they only serve as
+                    # separator between other bitfields, to force them
+                    # into separate words.
+                    pass
+                prev_bitfield_size = 0
+
             else:
-                # Can the field start at the offset given by 'boffset'?  It
-                # can if it would entirely fit into an aligned ftype field.
-                bits_already_occupied = boffset - (field_offset_bytes * 8)
+                if (sflags & SF_MSVC_BITFIELDS) == 0:
+                    # GCC's algorithm
 
-                if bits_already_occupied + fbitsize > 8 * ftype.size:
-                    # it would not fit, we need to start at the next
-                    # allowed position
-                    field_offset_bytes += falign
-                    assert boffset < field_offset_bytes * 8
-                    boffset = field_offset_bytes * 8
-                    bitshift = 0
+                    # Can the field start at the offset given by 'boffset'?  It
+                    # can if it would entirely fit into an aligned ftype field.
+                    bits_already_occupied = boffset - (field_offset_bytes * 8)
+
+                    if bits_already_occupied + fbitsize > 8 * ftype.size:
+                        # it would not fit, we need to start at the next
+                        # allowed position
+                        field_offset_bytes += falign
+                        assert boffset < field_offset_bytes * 8
+                        boffset = field_offset_bytes * 8
+                        bitshift = 0
+                    else:
+                        bitshift = bits_already_occupied
+                        assert bitshift >= 0
+                    boffset += fbitsize
+
                 else:
-                    bitshift = bits_already_occupied
+                    # MSVC's algorithm
+
+                    # A bitfield is considered as taking the full width
+                    # of their declared type.  It can share some bits
+                    # with the previous field only if it was also a
+                    # bitfield and used a type of the same size.
+                    if (prev_bitfield_size == ftype.size and
+                        prev_bitfield_free >= fbitsize):
+                        # yes: reuse
+                        bitshift = 8 * prev_bitfield_size - prev_bitfield_free
+                    else:
+                        # no: start a new full field
+                        boffset = (boffset + falign*8-1) & ~(falign*8-1)
+                        boffset += ftype.size * 8
+                        bitshift = 0
+                        prev_bitfield_size = ftype.size
+                        prev_bitfield_free = 8 * prev_bitfield_size
+                    #
+                    prev_bitfield_free -= fbitsize
+                    field_offset_bytes = boffset / 8 - ftype.size
 
                 fld = ctypestruct.W_CField(ftype, field_offset_bytes,
                                            bitshift, fbitsize)
                 fields_list.append(fld)
                 fields_dict[fname] = fld
-            
-                boffset += fbitsize
 
         if boffset > boffsetmax:
             boffsetmax = boffset
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -2757,36 +2757,57 @@
     assert wr() is None
     py.test.raises(RuntimeError, from_handle, cast(BCharP, 0))
 
-def test_bitfield_as_gcc():
+def _test_bitfield_details(flag):
     BChar = new_primitive_type("char")
     BShort = new_primitive_type("short")
     BInt = new_primitive_type("int")
+    BUInt = new_primitive_type("unsigned int")
     BStruct = new_struct_type("foo1")
     complete_struct_or_union(BStruct, [('a', BChar, -1),
-                                       ('b', BInt, 9),
-                                       ('c', BChar, -1)])
-    assert typeoffsetof(BStruct, 'c') == (BChar, 3)
-    assert sizeof(BStruct) == 4
+                                       ('b1', BInt, 9),
+                                       ('b2', BUInt, 7),
+                                       ('c', BChar, -1)], -1, -1, -1, flag)
+    if flag == 0:   # gcc
+        assert typeoffsetof(BStruct, 'c') == (BChar, 3)
+        assert sizeof(BStruct) == 4
+    else:           # msvc
+        assert typeoffsetof(BStruct, 'c') == (BChar, 8)
+        assert sizeof(BStruct) == 12
     assert alignof(BStruct) == 4
     #
     BStruct = new_struct_type("foo2")
     complete_struct_or_union(BStruct, [('a', BChar, -1),
                                        ('',  BShort, 9),
-                                       ('c', BChar, -1)])
+                                       ('c', BChar, -1)], -1, -1, -1, flag)
     assert typeoffsetof(BStruct, 'c') == (BChar, 4)
-    assert sizeof(BStruct) == 5
-    assert alignof(BStruct) == 1
+    if flag == 0:   # gcc
+        assert sizeof(BStruct) == 5
+        assert alignof(BStruct) == 1
+    else:           # msvc
+        assert sizeof(BStruct) == 6
+        assert alignof(BStruct) == 2
     #
     BStruct = new_struct_type("foo2")
     complete_struct_or_union(BStruct, [('a', BChar, -1),
                                        ('',  BInt, 0),
                                        ('',  BInt, 0),
-                                       ('c', BChar, -1)])
-    assert typeoffsetof(BStruct, 'c') == (BChar, 4)
-    assert sizeof(BStruct) == 5
+                                       ('c', BChar, -1)], -1, -1, -1, flag)
+    if flag == 0:   # gcc
+        assert typeoffsetof(BStruct, 'c') == (BChar, 4)
+        assert sizeof(BStruct) == 5
+    else:           # msvc
+        assert typeoffsetof(BStruct, 'c') == (BChar, 1)
+        assert sizeof(BStruct) == 2
     assert alignof(BStruct) == 1
 
 
+def test_bitfield_as_gcc():
+    _test_bitfield_details(flag=0)
+
+def test_bitfield_as_msvc():
+    _test_bitfield_details(flag=1)
+
+
 def test_version():
     # this test is here mostly for PyPy
     assert __version__ == "0.7"
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
@@ -303,7 +303,7 @@
         return _absolute_import(space, modulename, baselevel,
                                 fromlist_w, tentative)
     finally:
-        lock.release_lock()
+        lock.release_lock(silent_after_fork=True)
 
 @jit.unroll_safe
 def absolute_import_try(space, modulename, baselevel, fromlist_w):
@@ -788,9 +788,13 @@
             self.lockowner = me
         self.lockcounter += 1
 
-    def release_lock(self):
+    def release_lock(self, silent_after_fork):
         me = self.space.getexecutioncontext()   # used as thread ident
         if self.lockowner is not me:
+            if self.lockowner is None and silent_after_fork:
+                # Too bad.  This situation can occur if a fork() occurred
+                # with the import lock held, and we're the child.
+                return
             if not self._can_have_lock():
                 return
             space = self.space
diff --git a/pypy/module/imp/interp_imp.py b/pypy/module/imp/interp_imp.py
--- a/pypy/module/imp/interp_imp.py
+++ b/pypy/module/imp/interp_imp.py
@@ -177,7 +177,7 @@
 
 def release_lock(space):
     if space.config.objspace.usemodules.thread:
-        importing.getimportlock(space).release_lock()
+        importing.getimportlock(space).release_lock(silent_after_fork=False)
 
 def reinit_lock(space):
     if space.config.objspace.usemodules.thread:
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
@@ -30,7 +30,7 @@
 def new_dtype_getter(name):
     def _get_dtype(space):
         from pypy.module.micronumpy.interp_dtype import get_dtype_cache
-        return getattr(get_dtype_cache(space), "w_%sdtype" % name)
+        return get_dtype_cache(space).dtypes_by_name[name]
 
     def new(space, w_subtype, w_value):
         dtype = _get_dtype(space)
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
@@ -273,7 +273,6 @@
 
         fields = space.getitem(w_data, space.wrap(4))
         self.set_fields(space, fields)
-        print self.itemtype
 
 class W_ComplexDtype(W_Dtype):
     def __init__(self, itemtype, num, kind, name, char, w_box_type,
diff --git a/pypy/module/micronumpy/test/test_scalar.py b/pypy/module/micronumpy/test/test_scalar.py
--- a/pypy/module/micronumpy/test/test_scalar.py
+++ b/pypy/module/micronumpy/test/test_scalar.py
@@ -21,7 +21,3 @@
 
         a = zeros(3)
         assert loads(dumps(sum(a))) == sum(a)
-
-    def setup_class(cls):
-        import py
-        py.test.xfail("FIXME: dtype('int32') == dtype('int32') fails")
diff --git a/pypy/module/test_lib_pypy/test_ctypes_config_cache.py b/pypy/module/test_lib_pypy/test_ctypes_config_cache.py
--- a/pypy/module/test_lib_pypy/test_ctypes_config_cache.py
+++ b/pypy/module/test_lib_pypy/test_ctypes_config_cache.py
@@ -41,6 +41,10 @@
     assert 'LOG_NOTICE' in d
 
 def test_resource():
+    try:
+        import lib_pypy.resource
+    except ImportError:
+        py.test.skip('no syslog on this platform')
     d = run('resource.ctc.py', '_resource_cache.py')
     assert 'RLIM_NLIMITS' in d
 
diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -352,9 +352,8 @@
         def std_wp(self, r):
             length = len(r)
             if do_unicode and isinstance(r, str):
-                # convert string to unicode explicitely here
-                from pypy.objspace.std.unicodetype import plain_str2unicode
-                r = plain_str2unicode(self.space, r)
+                # convert string to unicode using the default encoding
+                r = self.space.unicode_w(self.space.wrap(r))
             prec = self.prec
             if prec == -1 and self.width == 0:
                 # fast path
@@ -509,12 +508,10 @@
             result = formatter.format()
         except NeedUnicodeFormattingError:
             # fall through to the unicode case
-            from pypy.objspace.std.unicodetype import plain_str2unicode
-            fmt = plain_str2unicode(space, fmt)
+            pass
         else:
             return space.wrap(result)
-    else:
-        fmt = space.unicode_w(w_fmt)
+    fmt = space.unicode_w(w_fmt)
     formatter = UnicodeFormatter(space, fmt, values_w, w_valuedict)
     result = formatter.format()
     return space.wrap(result)
diff --git a/pypy/objspace/std/test/test_stringobject.py b/pypy/objspace/std/test/test_stringobject.py
--- a/pypy/objspace/std/test/test_stringobject.py
+++ b/pypy/objspace/std/test/test_stringobject.py
@@ -530,6 +530,12 @@
                 del sys.modules[module_name]
             temp_sys.setdefaultencoding('utf-8')
             assert u''.join(['\xc3\xa1']) == u'\xe1'
+            #
+            assert ('\xc3\xa1:%s' % u'\xe2') == u'\xe1:\xe2'
+            class Foo(object):
+                def __repr__(self):
+                    return '\xc3\xa2'
+            assert u'\xe1:%r' % Foo() == u'\xe1:\xe2'
         finally:
             temp_sys.setdefaultencoding(old_encoding)
             sys.modules.update(self.original_modules)
diff --git a/pypy/objspace/std/unicodetype.py b/pypy/objspace/std/unicodetype.py
--- a/pypy/objspace/std/unicodetype.py
+++ b/pypy/objspace/std/unicodetype.py
@@ -13,22 +13,6 @@
     from pypy.objspace.std.unicodeobject import W_UnicodeObject
     return W_UnicodeObject(uni)
 
-def plain_str2unicode(space, s):
-    try:
-        return unicode(s)
-    except UnicodeDecodeError:
-        for i in range(len(s)):
-            if ord(s[i]) > 127:
-                raise OperationError(
-                    space.w_UnicodeDecodeError,
-                    space.newtuple([
-                    space.wrap('ascii'),
-                    space.wrap(s),
-                    space.wrap(i),
-                    space.wrap(i+1),
-                    space.wrap("ordinal not in range(128)")]))
-        assert False, "unreachable"
-
 
 unicode_capitalize = SMM('capitalize', 1,
                          doc='S.capitalize() -> unicode\n\nReturn a'
diff --git a/rpython/jit/backend/arm/assembler.py b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -8,6 +8,7 @@
     JITFRAME_FIXED_SIZE)
 from rpython.jit.backend.arm.codebuilder import InstrBuilder, OverwritingBuilder
 from rpython.jit.backend.arm.locations import imm, StackLocation
+from rpython.jit.backend.arm.helper.regalloc import VMEM_imm_size
 from rpython.jit.backend.arm.opassembler import ResOpAssembler
 from rpython.jit.backend.arm.regalloc import (Regalloc,
     CoreRegisterManager, check_imm_arg, VFPRegisterManager,
@@ -961,7 +962,7 @@
             return self._load_core_reg(mc, target, base, ofs, cond, helper)
 
     def _load_vfp_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
-        if check_imm_arg(ofs):
+        if check_imm_arg(ofs, VMEM_imm_size):
             mc.VLDR(target.value, base.value, imm=ofs, cond=cond)
         else:
             mc.gen_load_int(helper.value, ofs, cond=cond)
@@ -982,7 +983,7 @@
             return self._store_core_reg(mc, source, base, ofs, cond, helper)
 
     def _store_vfp_reg(self, mc, source, base, ofs, cond=c.AL, helper=r.ip):
-        if check_imm_arg(ofs):
+        if check_imm_arg(ofs, VMEM_imm_size):
             mc.VSTR(source.value, base.value, imm=ofs, cond=cond)
         else:
             mc.gen_load_int(helper.value, ofs, cond=cond)
diff --git a/rpython/jit/backend/arm/callbuilder.py b/rpython/jit/backend/arm/callbuilder.py
--- a/rpython/jit/backend/arm/callbuilder.py
+++ b/rpython/jit/backend/arm/callbuilder.py
@@ -52,6 +52,8 @@
 
     def _push_stack_args(self, stack_args, on_stack):
         assert on_stack % 8 == 0
+        if on_stack == 0:
+            return
         self._adjust_sp(-on_stack)
         self.current_sp = on_stack
         ofs = 0
@@ -71,7 +73,7 @@
             else:
                 self.mc.gen_load_int(r.ip.value, n)
                 self.mc.ADD_rr(r.sp.value, r.sp.value, r.ip.value)
-        else:
+        elif n < 0:
             n = abs(n)
             if check_imm_arg(n):
                 self.mc.SUB_ri(r.sp.value, r.sp.value, n)
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
@@ -4,7 +4,10 @@
 from rpython.jit.metainterp.history import ConstInt
 from rpython.rlib.objectmodel import we_are_translated
 
-def check_imm_arg(arg, size=0xFF, allow_zero=True):
+VMEM_imm_size=0x3FC
+default_imm_size=0xFF
+
+def check_imm_arg(arg, size=default_imm_size, allow_zero=True):
     assert not isinstance(arg, ConstInt)
     if not we_are_translated():
         if not isinstance(arg, int):
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
@@ -15,6 +15,7 @@
                                                 gen_emit_unary_float_op,
                                                 saved_registers)
 from rpython.jit.backend.arm.helper.regalloc import check_imm_arg
+from rpython.jit.backend.arm.helper.regalloc import VMEM_imm_size
 from rpython.jit.backend.arm.codebuilder import InstrBuilder, OverwritingBuilder
 from rpython.jit.backend.arm.jump import remap_frame_layout
 from rpython.jit.backend.arm.regalloc import TempBox
@@ -23,6 +24,7 @@
 from rpython.jit.backend.llsupport.gcmap import allocate_gcmap
 from rpython.jit.backend.llsupport.descr import InteriorFieldDescr
 from rpython.jit.backend.llsupport.assembler import GuardToken, BaseAssembler
+from rpython.jit.backend.llsupport.regalloc import get_scale
 from rpython.jit.metainterp.history import (Box, AbstractFailDescr,
                                             INT, FLOAT, REF)
 from rpython.jit.metainterp.history import TargetToken
@@ -523,35 +525,9 @@
 
     def emit_op_setfield_gc(self, op, arglocs, regalloc, fcond):
         value_loc, base_loc, ofs, size = arglocs
-        if size.value == 8:
-            assert value_loc.is_vfp_reg()
-            # vstr only supports imm offsets
-            # so if the ofset is too large we add it to the base and use an
-            # offset of 0
-            if ofs.is_reg():
-                self.mc.ADD_rr(r.ip.value, base_loc.value, ofs.value)
-                base_loc = r.ip
-                ofs = imm(0)
-            else:
-                assert ofs.value % 4 == 0
-            self.mc.VSTR(value_loc.value, base_loc.value, ofs.value)
-        elif size.value == 4:
-            if ofs.is_imm():
-                self.mc.STR_ri(value_loc.value, base_loc.value, ofs.value)
-            else:
-                self.mc.STR_rr(value_loc.value, base_loc.value, ofs.value)
-        elif size.value == 2:
-            if ofs.is_imm():
-                self.mc.STRH_ri(value_loc.value, base_loc.value, ofs.value)
-            else:
-                self.mc.STRH_rr(value_loc.value, base_loc.value, ofs.value)
-        elif size.value == 1:
-            if ofs.is_imm():
-                self.mc.STRB_ri(value_loc.value, base_loc.value, ofs.value)
-            else:
-                self.mc.STRB_rr(value_loc.value, base_loc.value, ofs.value)
-        else:
-            assert 0
+        scale = get_scale(size.value)
+        self._write_to_mem(value_loc, base_loc,
+                                ofs, imm(scale), fcond)
         return fcond
 
     emit_op_setfield_raw = emit_op_setfield_gc
@@ -559,47 +535,8 @@
     def emit_op_getfield_gc(self, op, arglocs, regalloc, fcond):
         base_loc, ofs, res, size = arglocs
         signed = op.getdescr().is_field_signed()
-        if size.value == 8:
-            assert res.is_vfp_reg()
-            # vldr only supports imm offsets
-            # so if the ofset is too large we add it to the base and use an
-            # offset of 0
-            if ofs.is_reg():
-                self.mc.ADD_rr(r.ip.value, base_loc.value, ofs.value)
-                base_loc = r.ip
-                ofs = imm(0)
-            else:
-                assert ofs.value % 4 == 0
-            self.mc.VLDR(res.value, base_loc.value, ofs.value)
-        elif size.value == 4:
-            if ofs.is_imm():
-                self.mc.LDR_ri(res.value, base_loc.value, ofs.value)
-            else:
-                self.mc.LDR_rr(res.value, base_loc.value, ofs.value)
-        elif size.value == 2:
-            if ofs.is_imm():
-                if signed:
-                    self.mc.LDRSH_ri(res.value, base_loc.value, ofs.value)
-                else:
-                    self.mc.LDRH_ri(res.value, base_loc.value, ofs.value)
-            else:
-                if signed:
-                    self.mc.LDRSH_rr(res.value, base_loc.value, ofs.value)
-                else:
-                    self.mc.LDRH_rr(res.value, base_loc.value, ofs.value)
-        elif size.value == 1:
-            if ofs.is_imm():
-                if signed:
-                    self.mc.LDRSB_ri(res.value, base_loc.value, ofs.value)
-                else:
-                    self.mc.LDRB_ri(res.value, base_loc.value, ofs.value)
-            else:
-                if signed:
-                    self.mc.LDRSB_rr(res.value, base_loc.value, ofs.value)
-                else:
-                    self.mc.LDRB_rr(res.value, base_loc.value, ofs.value)
-        else:
-            assert 0
+        scale = get_scale(size.value)
+        self._load_from_mem(res, base_loc, ofs, imm(scale), signed, fcond)
         return fcond
 
     emit_op_getfield_raw = emit_op_getfield_gc
@@ -609,72 +546,44 @@
     def emit_op_getinteriorfield_gc(self, op, arglocs, regalloc, fcond):
         (base_loc, index_loc, res_loc,
             ofs_loc, ofs, itemsize, fieldsize) = arglocs
-        self.mc.gen_load_int(r.ip.value, itemsize.value)
-        self.mc.MUL(r.ip.value, index_loc.value, r.ip.value)
+        scale = get_scale(fieldsize.value)
+        tmploc, save = self.get_tmp_reg([base_loc, ofs_loc])
+        assert not save
+        self.mc.gen_load_int(tmploc.value, itemsize.value)
+        self.mc.MUL(tmploc.value, index_loc.value, tmploc.value)
         descr = op.getdescr()
         assert isinstance(descr, InteriorFieldDescr)
         signed = descr.fielddescr.is_field_signed()
         if ofs.value > 0:
             if ofs_loc.is_imm():
-                self.mc.ADD_ri(r.ip.value, r.ip.value, ofs_loc.value)
+                self.mc.ADD_ri(tmploc.value, tmploc.value, ofs_loc.value)
             else:
-                self.mc.ADD_rr(r.ip.value, r.ip.value, ofs_loc.value)
-
-        if fieldsize.value == 8:
-            # vldr only supports imm offsets
-            # so if the ofset is too large we add it to the base and use an
-            # offset of 0
-            assert res_loc.is_vfp_reg()
-            self.mc.ADD_rr(r.ip.value, base_loc.value, r.ip.value)
-            self.mc.VLDR(res_loc.value, r.ip.value, 0)
-        elif fieldsize.value == 4:
-            self.mc.LDR_rr(res_loc.value, base_loc.value, r.ip.value)
-        elif fieldsize.value == 2:
-            if signed:
-                self.mc.LDRSH_rr(res_loc.value, base_loc.value, r.ip.value)
-            else:
-                self.mc.LDRH_rr(res_loc.value, base_loc.value, r.ip.value)
-        elif fieldsize.value == 1:
-            if signed:
-                self.mc.LDRSB_rr(res_loc.value, base_loc.value, r.ip.value)
-            else:
-                self.mc.LDRB_rr(res_loc.value, base_loc.value, r.ip.value)
-        else:
-            assert 0
-
+                self.mc.ADD_rr(tmploc.value, tmploc.value, ofs_loc.value)
+        ofs_loc = tmploc
+        self._load_from_mem(res_loc, base_loc, ofs_loc,
+                                imm(scale), signed, fcond)
         return fcond
 
     def emit_op_setinteriorfield_gc(self, op, arglocs, regalloc, fcond):
         (base_loc, index_loc, value_loc,
             ofs_loc, ofs, itemsize, fieldsize) = arglocs
-        self.mc.gen_load_int(r.ip.value, itemsize.value)
-        self.mc.MUL(r.ip.value, index_loc.value, r.ip.value)
+        scale = get_scale(fieldsize.value)
+        tmploc, save = self.get_tmp_reg([base_loc, index_loc, value_loc, ofs_loc])
+        assert not save
+        self.mc.gen_load_int(tmploc.value, itemsize.value)
+        self.mc.MUL(tmploc.value, index_loc.value, tmploc.value)
         if ofs.value > 0:
             if ofs_loc.is_imm():
-                self.mc.ADD_ri(r.ip.value, r.ip.value, ofs_loc.value)
+                self.mc.ADD_ri(tmploc.value, tmploc.value, ofs_loc.value)
             else:
-                self.mc.ADD_rr(r.ip.value, r.ip.value, ofs_loc.value)
-        if fieldsize.value == 8:
-            # vstr only supports imm offsets
-            # so if the ofset is too large we add it to the base and use an
-            # offset of 0
-            assert value_loc.is_vfp_reg()
-            self.mc.ADD_rr(r.ip.value, base_loc.value, r.ip.value)
-            self.mc.VSTR(value_loc.value, r.ip.value, 0)
-        elif fieldsize.value == 4:
-            self.mc.STR_rr(value_loc.value, base_loc.value, r.ip.value)
-        elif fieldsize.value == 2:
-            self.mc.STRH_rr(value_loc.value, base_loc.value, r.ip.value)
-        elif fieldsize.value == 1:
-            self.mc.STRB_rr(value_loc.value, base_loc.value, r.ip.value)
-        else:
-            assert 0
+                self.mc.ADD_rr(tmploc.value, tmploc.value, ofs_loc.value)
+        self._write_to_mem(value_loc, base_loc, tmploc, imm(scale), fcond)
         return fcond
     emit_op_setinteriorfield_raw = emit_op_setinteriorfield_gc
 
     def emit_op_arraylen_gc(self, op, arglocs, regalloc, fcond):
         res, base_loc, ofs = arglocs
-        self.mc.LDR_ri(res.value, base_loc.value, ofs.value)
+        self.load_reg(self.mc, res, base_loc, ofs.value)
         return fcond
 
     def emit_op_setarrayitem_gc(self, op, arglocs, regalloc, fcond):
@@ -694,18 +603,40 @@
     def _write_to_mem(self, value_loc, base_loc, ofs_loc, scale, fcond=c.AL):
         if scale.value == 3:
             assert value_loc.is_vfp_reg()
-            assert ofs_loc.is_reg()
-            self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value)
-            self.mc.VSTR(value_loc.value, r.ip.value, cond=fcond)
+            # vstr only supports imm offsets
+            # so if the ofset is too large we add it to the base and use an
+            # offset of 0
+            if ofs_loc.is_reg():
+                tmploc, save = self.get_tmp_reg([value_loc, base_loc, ofs_loc])
+                assert not save
+                self.mc.ADD_rr(tmploc.value, base_loc.value, ofs_loc.value)
+                base_loc = tmploc
+                ofs_loc = imm(0)
+            else:
+                assert ofs_loc.is_imm()
+                assert ofs_loc.value % 4 == 0
+            self.mc.VSTR(value_loc.value, base_loc.value, ofs_loc.value)
         elif scale.value == 2:
-            self.mc.STR_rr(value_loc.value, base_loc.value, ofs_loc.value,
-                                                                    cond=fcond)
+            if ofs_loc.is_imm():
+                self.mc.STR_ri(value_loc.value, base_loc.value,
+                                ofs_loc.value, cond=fcond)
+            else:
+                self.mc.STR_rr(value_loc.value, base_loc.value,
+                                ofs_loc.value, cond=fcond)
         elif scale.value == 1:
-            self.mc.STRH_rr(value_loc.value, base_loc.value, ofs_loc.value,
-                                                                    cond=fcond)
+            if ofs_loc.is_imm():
+                self.mc.STRH_ri(value_loc.value, base_loc.value,
+                                ofs_loc.value, cond=fcond)
+            else:
+                self.mc.STRH_rr(value_loc.value, base_loc.value,
+                                ofs_loc.value, cond=fcond)
         elif scale.value == 0:
-            self.mc.STRB_rr(value_loc.value, base_loc.value, ofs_loc.value,
-                                                                    cond=fcond)
+            if ofs_loc.is_imm():
+                self.mc.STRB_ri(value_loc.value, base_loc.value,
+                                ofs_loc.value, cond=fcond)
+            else:
+                self.mc.STRB_rr(value_loc.value, base_loc.value,
+                                ofs_loc.value, cond=fcond)
         else:
             assert 0
 
@@ -731,33 +662,63 @@
             self.mc.ADD_ri(r.ip.value, ofs_loc.value, imm=ofs.value)
             ofs_loc = r.ip
         #
-        self._load_from_mem(res_loc, base_loc, ofs_loc, scale, signed)
+        self._load_from_mem(res_loc, base_loc, ofs_loc, scale, signed, fcond)
         return fcond
 
     def _load_from_mem(self, res_loc, base_loc, ofs_loc, scale,
                                             signed=False, fcond=c.AL):
         if scale.value == 3:
             assert res_loc.is_vfp_reg()
-            assert ofs_loc.is_reg()
-            self.mc.ADD_rr(r.ip.value, base_loc.value, ofs_loc.value)
-            self.mc.VLDR(res_loc.value, r.ip.value, cond=fcond)
+            # vldr only supports imm offsets
+            # if the offset is in a register we add it to the base and use a
+            # tmp reg
+            if ofs_loc.is_reg():
+                tmploc, save = self.get_tmp_reg([base_loc, ofs_loc])
+                assert not save
+                self.mc.ADD_rr(tmploc.value, base_loc.value, ofs_loc.value)
+                base_loc = tmploc
+                ofs_loc = imm(0)
+            else:
+                assert ofs_loc.is_imm()
+                assert ofs_loc.value % 4 == 0
+            self.mc.VLDR(res_loc.value, base_loc.value, ofs_loc.value, cond=fcond)
         elif scale.value == 2:
-            self.mc.LDR_rr(res_loc.value, base_loc.value,
-                                 ofs_loc.value, cond=fcond)
+            if ofs_loc.is_imm():
+                self.mc.LDR_ri(res_loc.value, base_loc.value,
+                                ofs_loc.value, cond=fcond)
+            else:
+                self.mc.LDR_rr(res_loc.value, base_loc.value,
+                                ofs_loc.value, cond=fcond)
         elif scale.value == 1:
-            if signed:
-                self.mc.LDRSH_rr(res_loc.value, base_loc.value,
-                                 ofs_loc.value, cond=fcond)
+            if ofs_loc.is_imm():
+                if signed:
+                    self.mc.LDRSH_ri(res_loc.value, base_loc.value,
+                                        ofs_loc.value, cond=fcond)
+                else:
+                    self.mc.LDRH_ri(res_loc.value, base_loc.value,
+                                        ofs_loc.value, cond=fcond)
             else:
-                self.mc.LDRH_rr(res_loc.value, base_loc.value,
-                                 ofs_loc.value, cond=fcond)
+                if signed:
+                    self.mc.LDRSH_rr(res_loc.value, base_loc.value,
+                                        ofs_loc.value, cond=fcond)
+                else:
+                    self.mc.LDRH_rr(res_loc.value, base_loc.value,
+                                        ofs_loc.value, cond=fcond)
         elif scale.value == 0:
-            if signed:
-                self.mc.LDRSB_rr(res_loc.value, base_loc.value,
-                                 ofs_loc.value, cond=fcond)
+            if ofs_loc.is_imm():
+                if signed:
+                    self.mc.LDRSB_ri(res_loc.value, base_loc.value,
+                                        ofs_loc.value, cond=fcond)
+                else:
+                    self.mc.LDRB_ri(res_loc.value, base_loc.value,
+                                        ofs_loc.value, cond=fcond)
             else:
-                self.mc.LDRB_rr(res_loc.value, base_loc.value,
-                                 ofs_loc.value, cond=fcond)
+                if signed:
+                    self.mc.LDRSB_rr(res_loc.value, base_loc.value,
+                                        ofs_loc.value, cond=fcond)
+                else:
+                    self.mc.LDRB_rr(res_loc.value, base_loc.value,
+                                        ofs_loc.value, cond=fcond)
         else:
             assert 0
 
@@ -770,7 +731,7 @@
         # no base offset
         assert ofs.value == 0
         signed = op.getdescr().is_item_signed()
-        self._load_from_mem(res_loc, base_loc, ofs_loc, scale, signed)
+        self._load_from_mem(res_loc, base_loc, ofs_loc, scale, signed, fcond)
         return fcond
 
     def emit_op_strlen(self, op, arglocs, regalloc, fcond):
@@ -993,7 +954,7 @@
                 assert result_loc.is_vfp_reg()
                 # we always have a register here, since we have to sync them
                 # before call_assembler
-                self.mc.VLDR(result_loc.value, r.r0.value, imm=ofs)
+                self.load_reg(self.mc, result_loc, r.r0, ofs=ofs)
             else:
                 assert result_loc is r.r0
                 ofs = self.cpu.unpack_arraydescr(descr)
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
@@ -13,7 +13,9 @@
                                                     prepare_cmp_op,
                                                     prepare_float_op,
                                                     check_imm_arg,
-                                                    check_imm_box
+                                                    check_imm_box,
+                                                    VMEM_imm_size,
+                                                    default_imm_size,
                                                     )
 from rpython.jit.backend.arm.jump import remap_frame_layout_mixed
 from rpython.jit.backend.arm.arch import WORD, JITFRAME_FIXED_SIZE
@@ -811,7 +813,8 @@
         ofs, size, sign = unpack_fielddescr(op.getdescr())
         base_loc = self.make_sure_var_in_reg(a0, boxes)
         value_loc = self.make_sure_var_in_reg(a1, boxes)
-        if check_imm_arg(ofs):
+        ofs_size = default_imm_size if size < 8 else VMEM_imm_size
+        if check_imm_arg(ofs, size=ofs_size):
             ofs_loc = imm(ofs)
         else:
             ofs_loc = self.get_scratch_reg(INT, boxes)
@@ -825,7 +828,8 @@
         ofs, size, sign = unpack_fielddescr(op.getdescr())
         base_loc = self.make_sure_var_in_reg(a0)
         immofs = imm(ofs)
-        if check_imm_arg(ofs):
+        ofs_size = default_imm_size if size < 8 else VMEM_imm_size
+        if check_imm_arg(ofs, size=ofs_size):
             ofs_loc = immofs
         else:
             ofs_loc = self.get_scratch_reg(INT, [a0])
@@ -846,7 +850,8 @@
         base_loc = self.make_sure_var_in_reg(op.getarg(0), args)
         index_loc = self.make_sure_var_in_reg(op.getarg(1), args)
         immofs = imm(ofs)
-        if check_imm_arg(ofs):
+        ofs_size = default_imm_size if fieldsize < 8 else VMEM_imm_size
+        if check_imm_arg(ofs, size=ofs_size):
             ofs_loc = immofs
         else:
             ofs_loc = self.get_scratch_reg(INT, args)
@@ -865,7 +870,8 @@
         index_loc = self.make_sure_var_in_reg(op.getarg(1), args)
         value_loc = self.make_sure_var_in_reg(op.getarg(2), args)
         immofs = imm(ofs)
-        if check_imm_arg(ofs):
+        ofs_size = default_imm_size if fieldsize < 8 else VMEM_imm_size
+        if check_imm_arg(ofs, size=ofs_size):
             ofs_loc = immofs
         else:
             ofs_loc = self.get_scratch_reg(INT, args)
@@ -890,8 +896,8 @@
         scale = get_scale(size)
         args = op.getarglist()
         base_loc = self.make_sure_var_in_reg(args[0], args)
+        value_loc = self.make_sure_var_in_reg(args[2], args)
         ofs_loc = self.make_sure_var_in_reg(args[1], args)
-        value_loc = self.make_sure_var_in_reg(args[2], args)
         assert check_imm_arg(ofs)
         return [value_loc, base_loc, ofs_loc, imm(scale), imm(ofs)]
     prepare_op_setarrayitem_raw = prepare_op_setarrayitem_gc
diff --git a/rpython/jit/backend/arm/test/test_regalloc_mov.py b/rpython/jit/backend/arm/test/test_regalloc_mov.py
--- a/rpython/jit/backend/arm/test/test_regalloc_mov.py
+++ b/rpython/jit/backend/arm/test/test_regalloc_mov.py
@@ -436,7 +436,7 @@
         self.push(sf, e)
 
     def test_push_large_stackfloat(self):
-        sf = stack_float(100)
+        sf = stack_float(1000)
         e = [
             mi('gen_load_int', ip.value, sf.value, cond=AL),
             mi('ADD_rr', ip.value, fp.value, ip.value, cond=AL),
diff --git a/rpython/jit/metainterp/test/test_fficall.py b/rpython/jit/metainterp/test/test_fficall.py
--- a/rpython/jit/metainterp/test/test_fficall.py
+++ b/rpython/jit/metainterp/test/test_fficall.py
@@ -17,7 +17,7 @@
 def get_description(atypes, rtype):
     p = lltype.malloc(CIF_DESCRIPTION, len(atypes),
                       flavor='raw', immortal=True)
-    p.abi = 42
+    p.abi = 1     # default
     p.nargs = len(atypes)
     p.rtype = rtype
     p.atypes = lltype.malloc(FFI_TYPE_PP.TO, len(atypes),
diff --git a/rpython/rlib/ropenssl.py b/rpython/rlib/ropenssl.py
--- a/rpython/rlib/ropenssl.py
+++ b/rpython/rlib/ropenssl.py
@@ -9,7 +9,7 @@
 link_files = []
 include_dirs = []
 if sys.platform == 'win32' and platform.name != 'mingw32':
-    libraries = ['libeay32', 'ssleay32',
+    libraries = ['libeay32', 'ssleay32', 'zlib1',
                  'user32', 'advapi32', 'gdi32', 'msvcrt', 'ws2_32']
     includes = [
         # ssl.h includes winsock.h, which will conflict with our own
diff --git a/rpython/rlib/rposix.py b/rpython/rlib/rposix.py
--- a/rpython/rlib/rposix.py
+++ b/rpython/rlib/rposix.py
@@ -103,11 +103,10 @@
     _set_errno(rffi.cast(INT, errno))
 
 if os.name == 'nt':
-    is_valid_fd = rffi.llexternal(
+    is_valid_fd = jit.dont_look_inside(rffi.llexternal(
         "_PyVerify_fd", [rffi.INT], rffi.INT,
         compilation_info=errno_eci,
-        )
-    @jit.dont_look_inside
+        ))
     def validate_fd(fd):
         if not is_valid_fd(fd):
             raise OSError(get_errno(), 'Bad file descriptor')
diff --git a/rpython/rlib/rstruct/runpack.py b/rpython/rlib/rstruct/runpack.py
--- a/rpython/rlib/rstruct/runpack.py
+++ b/rpython/rlib/rstruct/runpack.py
@@ -7,7 +7,6 @@
 from struct import unpack
 from rpython.rlib.rstruct.formatiterator import FormatIterator
 from rpython.rlib.rstruct.error import StructError
-from rpython.rlib.rstruct.nativefmttable import native_is_bigendian
 
 class MasterReader(object):
     def __init__(self, s):
@@ -30,9 +29,9 @@
 
 def reader_for_pos(pos):
     class ReaderForPos(AbstractReader):
-        def __init__(self, mr):
+        def __init__(self, mr, bigendian):
             self.mr = mr
-            self.bigendian = native_is_bigendian
+            self.bigendian = bigendian
 
         def read(self, count):
             return self.mr.read(count)
@@ -64,6 +63,7 @@
         perform_lst = []
         miniglobals = {}
         miniglobals.update(globals())
+        miniglobals['bigendian'] = self.bigendian
         for i in rg:
             fmtdesc, rep, mask = self.formats[i]
             miniglobals['unpacker%d' % i] = fmtdesc.unpack
@@ -74,8 +74,8 @@
             else:
                 perform_lst.append('unpacker%d(reader%d, %d)' % (i, i, rep))
             miniglobals['reader_cls%d' % i] = reader_for_pos(i)
-        readers = ";".join(["reader%d = reader_cls%d(master_reader)" % (i, i)
-                             for i in rg])
+        readers = ";".join(["reader%d = reader_cls%d(master_reader, bigendian)"
+                            % (i, i) for i in rg])
         perform = ";".join(perform_lst)
         unpackers = ','.join(['reader%d.value' % i for i in rg])
         source = py.code.Source("""
diff --git a/rpython/rlib/rstruct/test/test_runpack.py b/rpython/rlib/rstruct/test/test_runpack.py
--- a/rpython/rlib/rstruct/test/test_runpack.py
+++ b/rpython/rlib/rstruct/test/test_runpack.py
@@ -26,6 +26,18 @@
         assert fn() == 123
         assert self.interpret(fn, []) == 123
 
+    def test_unpack_big_endian(self):
+        def fn():
+            return runpack(">i", "\x01\x02\x03\x04")
+        assert fn() == 0x01020304
+        assert self.interpret(fn, []) == 0x01020304
+
+    def test_unpack_double_big_endian(self):
+        def fn():
+            return runpack(">d", "testtest")
+        assert fn() == struct.unpack(">d", "testtest")[0]
+        assert self.interpret(fn, []) == struct.unpack(">d", "testtest")[0]
+
 class TestLLType(BaseTestRStruct, LLRtypeMixin):
     pass
 
diff --git a/rpython/rlib/rzlib.py b/rpython/rlib/rzlib.py
--- a/rpython/rlib/rzlib.py
+++ b/rpython/rlib/rzlib.py
@@ -10,7 +10,7 @@
 
 
 if compiler.name == "msvc":
-    libname = 'zlib'
+    libname = 'zlib1' # since version 1.1.4 and later, see http://www.zlib.net/DLL_FAQ.txt
 else:
     libname = 'z'
 eci = ExternalCompilationInfo(
diff --git a/rpython/rtyper/tool/test/test_rffi_platform.py b/rpython/rtyper/tool/test/test_rffi_platform.py
--- a/rpython/rtyper/tool/test/test_rffi_platform.py
+++ b/rpython/rtyper/tool/test/test_rffi_platform.py
@@ -288,9 +288,6 @@
     assert a % struct.calcsize("P") == 0
 
 def test_external_lib():
-    # XXX this one seems to be a bit too platform-specific. Check
-    #     how to test it on windows correctly (using so_prefix?)
-    #     and what are alternatives to LD_LIBRARY_PATH
     eci = ExternalCompilationInfo()
     c_source = """
     int f(int a, int b)
@@ -298,12 +295,17 @@
         return (a + b);
     }
     """
+    if platform.name == 'mscv':
+        c_source = '__declspec(dllexport) ' + c_source
+        libname = 'libc_lib'
+    else:
+        libname = 'c_lib'
     tmpdir = udir.join('external_lib').ensure(dir=1)
     c_file = tmpdir.join('libc_lib.c')
     c_file.write(c_source)
     l = platform.compile([c_file], eci, standalone=False)
     eci = ExternalCompilationInfo(
-        libraries = ['c_lib'],
+        libraries = [libname],
         library_dirs = [str(tmpdir)]
         )
     rffi_platform.verify_eci(eci)
diff --git a/rpython/translator/c/gcc/test/test_asmgcroot.py b/rpython/translator/c/gcc/test/test_asmgcroot.py
--- a/rpython/translator/c/gcc/test/test_asmgcroot.py
+++ b/rpython/translator/c/gcc/test/test_asmgcroot.py
@@ -25,8 +25,8 @@
 
     @classmethod
     def make_config(cls):
-        if _MSVC and _WIN64:
-            py.test.skip("all asmgcroot tests disabled for MSVC X64")
+        if _MSVC:
+            py.test.skip("all asmgcroot tests disabled for MSVC")
         from rpython.config.translationoption import get_combined_translation_config
         config = get_combined_translation_config(translating=True)
         config.translation.gc = cls.gcpolicy
diff --git a/rpython/translator/c/test/test_genc.py b/rpython/translator/c/test/test_genc.py
--- a/rpython/translator/c/test/test_genc.py
+++ b/rpython/translator/c/test/test_genc.py
@@ -37,7 +37,7 @@
     if isinstance(v, float):
         from rpython.rlib.rfloat import formatd, DTSF_ADD_DOT_0
         return formatd(v, 'r', 0, DTSF_ADD_DOT_0)
-    return v
+    return str(v)   # always return a string, to get consistent types
 
 def parse_longlong(a):
     p0, p1 = a.split(":")
@@ -205,6 +205,28 @@
     py.test.raises(Exception, f1, "world")  # check that it's really typed
 
 
+def test_int_becomes_float():
+    # used to crash "very often": the long chain of mangle() calls end
+    # up converting the return value of f() from an int to a float, but
+    # if blocks are followed in random order by the annotator, it will
+    # very likely first follow the call to llrepr_out() done after the
+    # call to f(), getting an int first (and a float only later).
+    @specialize.arg(1)
+    def mangle(x, chain):
+        if chain:
+            return mangle(x, chain[1:])
+        return x - 0.5
+    def f(x):
+        if x > 10:
+            x = mangle(x, (1,1,1,1,1,1,1,1,1,1))
+        return x + 1
+
+    f1 = compile(f, [int])
+
+    assert f1(5) == 6
+    assert f1(12) == 12.5
+
+
 def test_string_arg():
     def f(s):
         total = 0
diff --git a/rpython/translator/platform/openbsd.py b/rpython/translator/platform/openbsd.py
--- a/rpython/translator/platform/openbsd.py
+++ b/rpython/translator/platform/openbsd.py
@@ -8,8 +8,9 @@
     DEFAULT_CC = "cc"
     name = "openbsd"
 
-    link_flags = os.environ.get("LDFLAGS", '-pthread').split()
-    cflags = os.environ.get("CFLAGS", "-O3 -pthread -fomit-frame-pointer -D_BSD_SOURCE").split()
+    link_flags = os.environ.get("LDFLAGS", "").split() + ['-pthread']
+    cflags = ['-O3', '-pthread', '-fomit-frame-pointer', '-D_BSD_SOURCE'
+             ] + os.environ.get("CFLAGS", "").split()
 
     def _libs(self, libraries):
         libraries=set(libraries + ("intl", "iconv", "compat"))
diff --git a/rpython/translator/platform/windows.py b/rpython/translator/platform/windows.py
--- a/rpython/translator/platform/windows.py
+++ b/rpython/translator/platform/windows.py
@@ -28,6 +28,8 @@
     return _get_compiler_type(cc, False)
 
 def Windows_x64(cc=None):
+    raise Exception("Win64 is not supported.  You must either build for Win32"
+                    " or contribute the missing support in PyPy.")
     return _get_compiler_type(cc, True)
     
 def _get_msvc_env(vsver, x64flag):


More information about the pypy-commit mailing list