[pypy-commit] pypy py3k: hg merge default

rlamy pypy.commits at gmail.com
Mon Jun 13 11:51:39 EDT 2016


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3k
Changeset: r85135:fef0c44d0976
Date: 2016-06-13 16:50 +0100
http://bitbucket.org/pypy/pypy/changeset/fef0c44d0976/

Log:	hg merge default

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
@@ -5,6 +5,9 @@
 .. this is a revision shortly after release-pypy2.7-v5.3
 .. startrev: 873218a739f1
 
+.. pull request #455
+Add sys.{get,set}dlopenflags, for cpyext extensions.
+
 .. branch: fix-gen-dfa
 
 Resolves an issue with the generator script to build the dfa for Python syntax.
@@ -19,3 +22,12 @@
 .. branch: s390x-5.3-catchup
 
 Implement the backend related changes for s390x.
+
+.. branch: incminimark-ll_assert
+.. branch: vmprof-openbsd
+
+.. branch: testing-cleanup
+
+Simplify handling of interp-level tests and make it more forward-
+compatible.
+
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -1203,7 +1203,7 @@
 
     def test_const_fold_unicode_subscr(self, monkeypatch):
         source = """def f():
-        return "abc"[0]
+        return u"abc"[0]
         """
         counts = self.count_instructions(source)
         if 0:   # xxx later?
@@ -1211,14 +1211,14 @@
 
         # getitem outside of the BMP should not be optimized
         source = """def f():
-        return "\U00012345"[0]
+        return u"\U00012345"[0]
         """
         counts = self.count_instructions(source)
         assert counts == {ops.LOAD_CONST: 2, ops.BINARY_SUBSCR: 1,
                           ops.RETURN_VALUE: 1}
 
         source = """def f():
-        return "\U00012345abcdef"[3]
+        return u"\U00012345abcdef"[3]
         """
         counts = self.count_instructions(source)
         assert counts == {ops.LOAD_CONST: 2, ops.BINARY_SUBSCR: 1,
@@ -1226,7 +1226,7 @@
 
         monkeypatch.setattr(optimize, "MAXUNICODE", 0xFFFF)
         source = """def f():
-        return "\uE01F"[0]
+        return u"\uE01F"[0]
         """
         counts = self.count_instructions(source)
         if 0:   # xxx later?
@@ -1236,7 +1236,7 @@
         # getslice is not yet optimized.
         # Still, check a case which yields the empty string.
         source = """def f():
-        return "abc"[:0]
+        return u"abc"[:0]
         """
         counts = self.count_instructions(source)
         assert counts == {ops.LOAD_CONST: 3, ops.BUILD_SLICE: 1,
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,21 +2,10 @@
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.lltypesystem.lloperation import llop
 from rpython.rlib.rarithmetic import r_uint, intmask
+from rpython.rlib.rarithmetic import int_c_div, int_c_mod
 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
- at jit.dont_look_inside
-def _int_floordiv(n, m):
-    return llop.int_floordiv(lltype.Signed, n, m)
-
- at jit.dont_look_inside
-def _int_mod(n, m):
-    return llop.int_mod(lltype.Signed, n, m)
-
-
 @unwrap_spec(n=int, m=int)
 def int_add(space, n, m):
     return space.wrap(llop.int_add(lltype.Signed, n, m))
@@ -31,11 +20,11 @@
 
 @unwrap_spec(n=int, m=int)
 def int_floordiv(space, n, m):
-    return space.wrap(_int_floordiv(n, m))
+    return space.wrap(int_c_div(n, m))
 
 @unwrap_spec(n=int, m=int)
 def int_mod(space, n, m):
-    return space.wrap(_int_mod(n, m))
+    return space.wrap(int_c_mod(n, m))
 
 @unwrap_spec(n=int, m=int)
 def int_lshift(space, n, m):
diff --git a/pypy/module/_cffi_backend/ccallback.py b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -220,6 +220,11 @@
         if rffi.cast(lltype.Signed, res) != clibffi.FFI_OK:
             raise oefmt(space.w_SystemError,
                         "libffi failed to build this callback")
+        if closure_ptr.c_user_data != unique_id:
+            raise oefmt(space.w_SystemError,
+                "ffi_prep_closure(): bad user_data (it seems that the "
+                "version of the libffi library seen at runtime is "
+                "different from the 'ffi.h' file seen at compile-time)")
 
     def py_invoke(self, ll_res, ll_args):
         jitdriver1.jit_merge_point(callback=self,
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
@@ -1516,7 +1516,7 @@
     try:
         ll_libname = rffi.str2charp(path)
         try:
-            dll = rdynload.dlopen(ll_libname)
+            dll = rdynload.dlopen(ll_libname, space.sys.dlopenflags)
         finally:
             lltype.free(ll_libname, flavor='raw')
     except rdynload.DLOpenError as e:
diff --git a/pypy/module/cpyext/include/pymem.h b/pypy/module/cpyext/include/pymem.h
--- a/pypy/module/cpyext/include/pymem.h
+++ b/pypy/module/cpyext/include/pymem.h
@@ -1,5 +1,11 @@
 #include <stdlib.h>
 
+#ifndef Py_PYMEM_H
+#define Py_PYMEM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #define PyMem_MALLOC(n)		malloc((n) ? (n) : 1)
 #define PyMem_REALLOC(p, n)	realloc((p), (n) ? (n) : 1)
@@ -44,3 +50,9 @@
  */
 #define PyMem_Del               PyMem_Free
 #define PyMem_DEL               PyMem_FREE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_PYMEM_H */
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -443,7 +443,7 @@
             if not hasattr(os, "fork"):
                 skip("Need fork() to test execv()")
             try:
-                output = "caf\xe9 \u1234\n".encode(sys.getfilesystemencoding())
+                output = u"caf\xe9 \u1234\n".encode(sys.getfilesystemencoding())
             except UnicodeEncodeError:
                 skip("encoding not good enough")
             pid = os.fork()
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
@@ -23,7 +23,7 @@
             guard_true(i14, descr=...)
             guard_not_invalidated(descr=...)
             i16 = int_eq(i6, %d)
-            i19 = call_i(ConstClass(ll_int_mod__Signed_Signed), i6, i10, descr=<Calli . ii EF=0 OS=14>)
+            i19 = call_i(ConstClass(ll_int_py_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)
diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py
--- a/pypy/module/sys/__init__.py
+++ b/pypy/module/sys/__init__.py
@@ -1,6 +1,7 @@
 from pypy.interpreter.mixedmodule import MixedModule
 from pypy.interpreter.error import OperationError
 from rpython.rlib.objectmodel import we_are_translated
+from rpython.rlib import rdynload
 import sys
 
 _WIN = sys.platform == 'win32'
@@ -18,6 +19,7 @@
         self.defaultencoding = "utf-8"
         self.filesystemencoding = None
         self.debug = True
+        self.dlopenflags = rdynload._dlopen_default_mode()
 
     interpleveldefs = {
         '__name__'              : '(space.wrap("sys"))',
@@ -79,6 +81,8 @@
         'int_info'              : 'system.get_int_info(space)',
         'hash_info'             : 'system.get_hash_info(space)',
         'float_repr_style'      : 'system.get_float_repr_style(space)',
+        'getdlopenflags'        : 'system.getdlopenflags',
+        'setdlopenflags'        : 'system.setdlopenflags',
         }
 
     if sys.platform == 'win32':
diff --git a/pypy/module/sys/system.py b/pypy/module/sys/system.py
--- a/pypy/module/sys/system.py
+++ b/pypy/module/sys/system.py
@@ -108,3 +108,9 @@
     ]
     w_thread_info = app.wget(space, "thread_info")
     return space.call_function(w_thread_info, space.newtuple(info_w))
+
+def getdlopenflags(space):
+    return space.wrap(space.sys.dlopenflags)
+
+def setdlopenflags(space, w_flags):
+    space.sys.dlopenflags = space.int_w(w_flags)
diff --git a/pypy/module/sys/test/test_sysmodule.py b/pypy/module/sys/test/test_sysmodule.py
--- a/pypy/module/sys/test/test_sysmodule.py
+++ b/pypy/module/sys/test/test_sysmodule.py
@@ -478,14 +478,12 @@
 
     def test_dlopenflags(self):
         import sys
-        if hasattr(sys, "setdlopenflags"):
-            assert hasattr(sys, "getdlopenflags")
-            raises(TypeError, sys.getdlopenflags, 42)
-            oldflags = sys.getdlopenflags()
-            raises(TypeError, sys.setdlopenflags)
-            sys.setdlopenflags(oldflags+1)
-            assert sys.getdlopenflags() == oldflags+1
-            sys.setdlopenflags(oldflags)
+        raises(TypeError, sys.getdlopenflags, 42)
+        oldflags = sys.getdlopenflags()
+        raises(TypeError, sys.setdlopenflags)
+        sys.setdlopenflags(oldflags+1)
+        assert sys.getdlopenflags() == oldflags+1
+        sys.setdlopenflags(oldflags)
 
     def test_refcount(self):
         import sys
@@ -661,7 +659,7 @@
 class AppTestSysSettracePortedFromCpython(object):
     def test_sys_settrace(self):
         import sys
-        
+
         class Tracer:
             def __init__(self):
                 self.events = []
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -427,11 +427,11 @@
 class FakeModule(W_Root):
     def __init__(self):
         self.w_dict = w_some_obj()
-
     def get(self, name):
         name + "xx"   # check that it's a string
         return w_some_obj()
 FakeObjSpace.sys = FakeModule()
 FakeObjSpace.sys.filesystemencoding = 'foobar'
 FakeObjSpace.sys.defaultencoding = 'ascii'
+FakeObjSpace.sys.dlopenflags = 123
 FakeObjSpace.builtin = FakeModule()
diff --git a/pypy/objspace/std/stringmethods.py b/pypy/objspace/std/stringmethods.py
--- a/pypy/objspace/std/stringmethods.py
+++ b/pypy/objspace/std/stringmethods.py
@@ -181,6 +181,7 @@
             return space.newint(value.count(sub, start, end))
         else:
             res = count(value, sub, start, end)
+            assert res >= 0
             return space.wrap(max(res, 0))
 
     def descr_decode(self, space, w_encoding=None, w_errors=None):
diff --git a/pypy/objspace/std/test/test_bytearrayobject.py b/pypy/objspace/std/test/test_bytearrayobject.py
--- a/pypy/objspace/std/test/test_bytearrayobject.py
+++ b/pypy/objspace/std/test/test_bytearrayobject.py
@@ -218,6 +218,7 @@
 
         check(bytearray(b'abc').replace(b'b', bytearray(b'd')), b'adc')
         check(bytearray(b'abc').replace(b'b', b'd'), b'adc')
+        check(bytearray(b'').replace(b'a', b'ab'), b'')
 
         check(bytearray(b'abc').upper(), b'ABC')
         check(bytearray(b'ABC').lower(), b'abc')
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -3,10 +3,12 @@
 It uses 'pypy/goal/pypy-c' and parts of the rest of the working
 copy.  Usage:
 
-    package.py [--options] pypy-VER-PLATFORM
+    package.py [--options] --archive-name=pypy-VER-PLATFORM
 
 The output is found in the directory from --builddir,
 by default /tmp/usession-YOURNAME/build/.
+
+For a list of all options, see 'package.py --help'.
 """
 
 import shutil
@@ -64,6 +66,7 @@
     name = options.name
     if not name:
         name = 'pypy-nightly'
+    assert '/' not in name
     rename_pypy_c = options.pypy_c
     override_pypy_c = options.override_pypy_c
 
@@ -299,26 +302,12 @@
         help='destination dir for archive')
     parser.add_argument('--override_pypy_c', type=str, default='',
         help='use as pypy exe instead of pypy/goal/pypy-c')
-    # Positional arguments, for backward compatability with buldbots
-    parser.add_argument('extra_args', help='optional interface to positional arguments', nargs=argparse.REMAINDER,
-        metavar='[archive-name] [rename_pypy_c] [targetdir] [override_pypy_c]',
-        )
     options = parser.parse_args(args)
 
-    # Handle positional arguments, choke if both methods are used
-    for i,target, default in ([1, 'name', ''], [2, 'pypy_c', pypy_exe],
-                              [3, 'targetdir', ''], [4,'override_pypy_c', '']):
-        if len(options.extra_args)>i:
-            if getattr(options, target) != default:
-                print 'positional argument',i,target,'already has value',getattr(options, target)
-                parser.print_help()
-                return
-            setattr(options, target, options.extra_args[i])
     if os.environ.has_key("PYPY_PACKAGE_NOSTRIP"):
         options.nostrip = True
-
     if os.environ.has_key("PYPY_PACKAGE_WITHOUTTK"):
-        options.tk = True
+        options.no_tk = True
     if not options.builddir:
         # The import actually creates the udir directory
         from rpython.tool.udir import udir
diff --git a/pypy/tool/release/test/test_package.py b/pypy/tool/release/test/test_package.py
--- a/pypy/tool/release/test/test_package.py
+++ b/pypy/tool/release/test/test_package.py
@@ -21,8 +21,10 @@
 
     def test_dir_structure(self, test='test'):
         retval, builddir = package.package(
-            '--without-cffi', str(py.path.local(pypydir).dirpath()),
-            test, self.rename_pypy_c, _fake=True)
+            '--without-cffi',
+            '--archive-name', test,
+            '--rename_pypy_c', self.rename_pypy_c,
+            _fake=True)
         assert retval == 0
         prefix = builddir.join(test)
         cpyver = '%d' % CPYTHON_VERSION[0]
@@ -71,8 +73,9 @@
         builddir = udir.ensure("build", dir=True)
         retval, builddir = package.package(
             '--without-cffi', '--builddir', str(builddir),
-            str(py.path.local(pypydir).dirpath()),
-            test, self.rename_pypy_c, _fake=True)
+            '--archive-name', test,
+            '--rename_pypy_c', self.rename_pypy_c,
+            _fake=True)
 
     def test_with_zipfile_module(self):
         prev = package.USE_ZIPFILE_MODULE
diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py
--- a/rpython/jit/backend/llsupport/test/test_gc_integration.py
+++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py
@@ -324,17 +324,19 @@
         def check(frame):
             expected_size = 1
             idx = 0
+            fixed_size = self.cpu.JITFRAME_FIXED_SIZE
             if self.cpu.backend_name.startswith('arm'):
                 # jitframe fixed part is larger here
                 expected_size = 2
                 idx = 1
+                fixed_size -= 32
             assert len(frame.jf_gcmap) == expected_size
-            if self.cpu.IS_64_BIT:
-                exp_idx = self.cpu.JITFRAME_FIXED_SIZE + 1  # +1 from i0
-            else:
-                assert frame.jf_gcmap[idx]
-                exp_idx = self.cpu.JITFRAME_FIXED_SIZE - 32 * idx + 1 # +1 from i0
-            assert frame.jf_gcmap[idx] == (1 << (exp_idx + 1)) | (1 << exp_idx)
+            # check that we have two bits set, and that they are in two
+            # registers (p0 and p1 are moved away when doing p2, but not
+            # spilled, just moved to different registers)
+            bits = [n for n in range(fixed_size)
+                      if frame.jf_gcmap[idx] & (1<<n)]
+            assert len(bits) == 2
 
         self.cpu = self.getcpu(check)
         ops = '''
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
@@ -439,7 +439,7 @@
     prepare_int_lshift = helper.prepare_binary_op
     prepare_int_rshift = helper.prepare_binary_op
     prepare_uint_rshift = helper.prepare_binary_op
-    prepare_uint_mul_high = helper.prepare_int_mul_ovf
+    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/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -522,6 +522,7 @@
     # but be really compiled
     rewrite_op_int_abs                = _do_builtin_call
     rewrite_op_int_floordiv           = _do_builtin_call
+    rewrite_op_int_mod                = _do_builtin_call
     rewrite_op_llong_abs              = _do_builtin_call
     rewrite_op_llong_floordiv         = _do_builtin_call
     rewrite_op_llong_mod              = _do_builtin_call
@@ -531,7 +532,6 @@
     rewrite_op_gc_id                  = _do_builtin_call
     rewrite_op_gc_pin                 = _do_builtin_call
     rewrite_op_gc_unpin               = _do_builtin_call
-    rewrite_op_uint_mod               = _do_builtin_call
     rewrite_op_cast_float_to_uint     = _do_builtin_call
     rewrite_op_cast_uint_to_float     = _do_builtin_call
     rewrite_op_weakref_create         = _do_builtin_call
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
@@ -252,7 +252,7 @@
 def _ll_2_int_floordiv(x, y):
     # this is used only if the RPython program uses llop.int_floordiv()
     # explicitly.  For 'a // b', see _handle_int_special() in jtransform.py.
-    # This is the reverse of rpython.rtyper.rint.ll_int_floordiv(), i.e.
+    # This is the reverse of rpython.rtyper.rint.ll_int_py_div(), i.e.
     # the same logic as rpython.rtyper.lltypesystem.opimpl.op_int_floordiv
     # but written in a no-branch style.
     r = x // y
@@ -260,6 +260,13 @@
     # the JIT knows that if x and y are both positive, this is just 'r'
     return r + (((x ^ y) >> (LONG_BIT - 1)) & (p != x))
 
+def _ll_2_int_mod(x, y):
+    # same comments as _ll_2_int_floordiv()
+    r = x % y
+    # the JIT knows that if x and y are both positive, this doesn't change 'r'
+    r -= y & (((x ^ y) & (r | -r)) >> (LONG_BIT - 1))
+    return r
+
 
 def _ll_1_cast_uint_to_float(x):
     # XXX on 32-bit platforms, this should be done using cast_longlong_to_float
@@ -431,6 +438,7 @@
 inline_calls_to = [
     ('int_abs',              [lltype.Signed],                lltype.Signed),
     ('int_floordiv',         [lltype.Signed, lltype.Signed], lltype.Signed),
+    ('int_mod',              [lltype.Signed, lltype.Signed], lltype.Signed),
     ('ll_math.ll_math_sqrt', [lltype.Float],                 lltype.Float),
 ]
 
diff --git a/rpython/jit/codewriter/test/test_flatten.py b/rpython/jit/codewriter/test/test_flatten.py
--- a/rpython/jit/codewriter/test/test_flatten.py
+++ b/rpython/jit/codewriter/test/test_flatten.py
@@ -478,7 +478,7 @@
             except ZeroDivisionError:
                 return -42
         self.encoding_test(f, [7, 2], """
-            residual_call_ir_i $<* fn ll_int_floordiv_ovf_zer__Signed_Signed>, I[%i0, %i1], R[], <Descr> -> %i2
+            residual_call_ir_i $<* fn ll_int_py_div_ovf_zer__Signed_Signed>, I[%i0, %i1], R[], <Descr> -> %i2
             -live-
             catch_exception L1
             int_return %i2
@@ -505,7 +505,7 @@
                 return 42
         # XXX so far, this really produces a int_mod_ovf_zer...
         self.encoding_test(f, [7, 2], """
-            residual_call_ir_i $<* fn ll_int_mod_ovf_zer__Signed_Signed>, I[%i0, %i1], R[], <Descr> -> %i2
+            residual_call_ir_i $<* fn ll_int_py_mod_ovf_zer__Signed_Signed>, I[%i0, %i1], R[], <Descr> -> %i2
             -live-
             catch_exception L1
             int_return %i2
diff --git a/rpython/jit/codewriter/test/test_support.py b/rpython/jit/codewriter/test/test_support.py
--- a/rpython/jit/codewriter/test/test_support.py
+++ b/rpython/jit/codewriter/test/test_support.py
@@ -144,11 +144,13 @@
     assert _ll_1_int_abs(-10) == 10
     assert _ll_1_int_abs(-sys.maxint) == sys.maxint
 
-def test_int_floordiv():
+def test_int_floordiv_mod():
     from rpython.rtyper.lltypesystem.lloperation import llop
-    from rpython.jit.codewriter.support import _ll_2_int_floordiv
+    from rpython.jit.codewriter.support import _ll_2_int_floordiv, _ll_2_int_mod
     for x in range(-6, 7):
         for y in range(-3, 4):
             if y != 0:
                 assert (_ll_2_int_floordiv(x, y) ==
                         llop.int_floordiv(lltype.Signed, x, y))
+                assert (_ll_2_int_mod(x, y) ==
+                        llop.int_mod(lltype.Signed, x, y))
diff --git a/rpython/jit/metainterp/optimizeopt/intbounds.py b/rpython/jit/metainterp/optimizeopt/intbounds.py
--- a/rpython/jit/metainterp/optimizeopt/intbounds.py
+++ b/rpython/jit/metainterp/optimizeopt/intbounds.py
@@ -97,17 +97,14 @@
         self.emit_operation(op)
 
         r = self.getintbound(op)
-        if b2.is_constant():
-            val = b2.lower
-            if val >= 0:
-                r.intersect(IntBound(0, val))
-        elif b1.is_constant():
-            val = b1.lower
-            if val >= 0:
-                r.intersect(IntBound(0, val))
-        elif b1.known_ge(IntBound(0, 0)) and b2.known_ge(IntBound(0, 0)):
-            lesser = min(b1.upper, b2.upper)
-            r.intersect(IntBound(0, next_pow2_m1(lesser)))
+        pos1 = b1.known_ge(IntBound(0, 0))
+        pos2 = b2.known_ge(IntBound(0, 0))
+        if pos1 or pos2:
+            r.make_ge(IntBound(0, 0))
+        if pos1:
+            r.make_le(b1)
+        if pos2:
+            r.make_le(b2)
 
     def optimize_INT_SUB(self, op):
         self.emit_operation(op)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -5188,6 +5188,25 @@
         """
         self.optimize_loop(ops, ops)
 
+    def test_int_and_positive(self):
+        ops = """
+        [i0, i1]
+        i2 = int_ge(i1, 0)
+        guard_true(i2) []
+        i3 = int_and(i0, i1)
+        i4 = int_ge(i3, 0)
+        guard_true(i4) []
+        jump(i3)
+        """
+        expected = """
+        [i0, i1]
+        i2 = int_ge(i1, 0)
+        guard_true(i2) []
+        i3 = int_and(i0, i1)
+        jump(i3)
+        """
+        self.optimize_loop(ops, expected)
+
     def test_int_or_cmp_above_bounds(self):
         ops = """
         [p0,p1]
diff --git a/rpython/jit/metainterp/test/test_ajit.py b/rpython/jit/metainterp/test/test_ajit.py
--- a/rpython/jit/metainterp/test/test_ajit.py
+++ b/rpython/jit/metainterp/test/test_ajit.py
@@ -972,6 +972,58 @@
         assert res == expected
         # should contain a call_i(..., OS=OS_INT_PY_DIV)
 
+    def test_int_c_mod(self):
+        from rpython.rlib.rarithmetic import int_c_mod
+        myjitdriver = JitDriver(greens = [], reds = ['i', 't'])
+        def f(i):
+            t = 0
+            while i < 10:
+                myjitdriver.can_enter_jit(i=i, t=t)
+                myjitdriver.jit_merge_point(i=i, t=t)
+                t += int_c_mod(-100, i)
+                i += 1
+            return t
+        expected = -sum([100 % n for n in range(1, 10)])
+        assert f(1) == expected
+        res = self.meta_interp(f, [1])
+        assert res == expected
+        # should contain a call_i(..., OS=OS_INT_PY_MOD)
+
+    def test_positive_c_div_mod(self):
+        from rpython.rlib.rarithmetic import int_c_div, int_c_mod
+        myjitdriver = JitDriver(greens = [], reds = ['i', 't'])
+        def f(i):
+            t = 0
+            while i < 10:
+                myjitdriver.can_enter_jit(i=i, t=t)
+                myjitdriver.jit_merge_point(i=i, t=t)
+                assert i > 0
+                t += int_c_div(100, i) - int_c_mod(100, i)
+                i += 1
+            return t
+        expected = sum([100 // n - 100 % n for n in range(1, 10)])
+        assert f(1) == expected
+        res = self.meta_interp(f, [1])
+        assert res == expected
+        # all the correction code should be dead now, xxx test that
+
+    def test_int_c_div_by_constant(self):
+        from rpython.rlib.rarithmetic import int_c_div
+        myjitdriver = JitDriver(greens = ['k'], reds = ['i', 't'])
+        def f(i, k):
+            t = 0
+            while i < 100:
+                myjitdriver.can_enter_jit(i=i, t=t, k=k)
+                myjitdriver.jit_merge_point(i=i, t=t, k=k)
+                t += int_c_div(i, k)
+                i += 1
+            return t
+        expected = sum([i // 10 for i in range(51, 100)])
+        assert f(-50, 10) == expected
+        res = self.meta_interp(f, [-50, 10])
+        assert res == expected
+        self.check_resops(call=0, uint_mul_high=2)
+
     def test_float(self):
         myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'res'])
         def f(x, y):
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -281,11 +281,12 @@
                  large_object=8*WORD,
                  ArenaCollectionClass=None,
                  **kwds):
+        "NOT_RPYTHON"
         MovingGCBase.__init__(self, config, **kwds)
         assert small_request_threshold % WORD == 0
         self.read_from_env = read_from_env
         self.nursery_size = nursery_size
-        
+
         self.small_request_threshold = small_request_threshold
         self.major_collection_threshold = major_collection_threshold
         self.growth_rate_max = growth_rate_max
@@ -644,6 +645,7 @@
             # Get the memory from the nursery.  If there is not enough space
             # there, do a collect first.
             result = self.nursery_free
+            ll_assert(result != llmemory.NULL, "uninitialized nursery")
             self.nursery_free = new_free = result + totalsize
             if new_free > self.nursery_top:
                 result = self.collect_and_reserve(totalsize)
@@ -703,6 +705,7 @@
             # Get the memory from the nursery.  If there is not enough space
             # there, do a collect first.
             result = self.nursery_free
+            ll_assert(result != llmemory.NULL, "uninitialized nursery")
             self.nursery_free = new_free = result + totalsize
             if new_free > self.nursery_top:
                 result = self.collect_and_reserve(totalsize)
@@ -1139,7 +1142,8 @@
         Implemented a bit obscurely by checking an unrelated flag
         that can never be set on a young object -- except if tid == -42.
         """
-        assert self.is_in_nursery(obj)
+        ll_assert(self.is_in_nursery(obj),
+                  "Can't forward an object outside the nursery.")
         tid = self.header(obj).tid
         result = (tid & GCFLAG_FINALIZATION_ORDERING != 0)
         if result:
@@ -1463,7 +1467,8 @@
                 objhdr.tid |= GCFLAG_CARDS_SET
 
         remember_young_pointer_from_array2._dont_inline_ = True
-        assert self.card_page_indices > 0
+        ll_assert(self.card_page_indices > 0,
+                  "non-positive card_page_indices")
         self.remember_young_pointer_from_array2 = (
             remember_young_pointer_from_array2)
 
@@ -1513,7 +1518,8 @@
             return True
         # ^^^ a fast path of write-barrier
         #
-        if source_hdr.tid & GCFLAG_HAS_CARDS != 0:
+        if (self.card_page_indices > 0 and     # check constant-folded
+            source_hdr.tid & GCFLAG_HAS_CARDS != 0):
             #
             if source_hdr.tid & GCFLAG_TRACK_YOUNG_PTRS == 0:
                 # The source object may have random young pointers.
@@ -1548,7 +1554,8 @@
 
     def manually_copy_card_bits(self, source_addr, dest_addr, length):
         # manually copy the individual card marks from source to dest
-        assert self.card_page_indices > 0
+        ll_assert(self.card_page_indices > 0,
+                  "non-positive card_page_indices")
         bytes = self.card_marking_bytes_for_length(length)
         #
         anybyte = 0
@@ -1721,12 +1728,15 @@
         nursery_barriers = self.AddressDeque()
         prev = self.nursery
         self.surviving_pinned_objects.sort()
-        assert self.pinned_objects_in_nursery == \
-            self.surviving_pinned_objects.length()
+        ll_assert(
+            self.pinned_objects_in_nursery == \
+            self.surviving_pinned_objects.length(),
+            "pinned_objects_in_nursery != surviving_pinned_objects.length()")
         while self.surviving_pinned_objects.non_empty():
             #
             cur = self.surviving_pinned_objects.pop()
-            assert cur >= prev
+            ll_assert(
+                cur >= prev, "pinned objects encountered in backwards order")
             #
             # clear the arena between the last pinned object (or arena start)
             # and the pinned object
@@ -1784,7 +1794,8 @@
         debug_stop("gc-minor")
 
     def _reset_flag_old_objects_pointing_to_pinned(self, obj, ignore):
-        assert self.header(obj).tid & GCFLAG_PINNED_OBJECT_PARENT_KNOWN
+        ll_assert(self.header(obj).tid & GCFLAG_PINNED_OBJECT_PARENT_KNOWN != 0,
+                  "!GCFLAG_PINNED_OBJECT_PARENT_KNOWN, but requested to reset.")
         self.header(obj).tid &= ~GCFLAG_PINNED_OBJECT_PARENT_KNOWN
 
     def _visit_old_objects_pointing_to_pinned(self, obj, ignore):
diff --git a/rpython/memory/gc/test/test_direct.py b/rpython/memory/gc/test/test_direct.py
--- a/rpython/memory/gc/test/test_direct.py
+++ b/rpython/memory/gc/test/test_direct.py
@@ -554,6 +554,7 @@
         assert res # we optimized it
         assert hdr_dst.tid & minimark.GCFLAG_TRACK_YOUNG_PTRS == 0 # and we copied the flag
         #
+        self.gc.card_page_indices = 128     # force > 0
         hdr_src.tid |= minimark.GCFLAG_TRACK_YOUNG_PTRS
         hdr_dst.tid |= minimark.GCFLAG_TRACK_YOUNG_PTRS
         hdr_src.tid |= minimark.GCFLAG_HAS_CARDS
diff --git a/rpython/rlib/clibffi.py b/rpython/rlib/clibffi.py
--- a/rpython/rlib/clibffi.py
+++ b/rpython/rlib/clibffi.py
@@ -148,7 +148,8 @@
                                                  ('elements', FFI_TYPE_PP)])
 
     ffi_cif = rffi_platform.Struct('ffi_cif', [])
-    ffi_closure = rffi_platform.Struct('ffi_closure', [])
+    ffi_closure = rffi_platform.Struct('ffi_closure',
+                                       [('user_data', rffi.VOIDP)])
 
 def add_simple_type(type_name):
     for name in ['size', 'alignment', 'type']:
diff --git a/rpython/rlib/rarithmetic.py b/rpython/rlib/rarithmetic.py
--- a/rpython/rlib/rarithmetic.py
+++ b/rpython/rlib/rarithmetic.py
@@ -662,6 +662,14 @@
     from rpython.rtyper.lltypesystem.lloperation import llop
     return llop.int_floordiv(lltype.Signed, x, y)
 
+def int_c_mod(x, y):
+    """Return the result of the C-style 'x % y'.  This differs from the
+    Python-style division if (x < 0  xor y < 0).
+    """
+    from rpython.rtyper.lltypesystem import lltype
+    from rpython.rtyper.lltypesystem.lloperation import llop
+    return llop.int_mod(lltype.Signed, x, y)
+
 @objectmodel.specialize.ll()
 def byteswap(arg):
     """ Convert little->big endian and the opposite
diff --git a/rpython/rlib/rdynload.py b/rpython/rlib/rdynload.py
--- a/rpython/rlib/rdynload.py
+++ b/rpython/rlib/rdynload.py
@@ -26,7 +26,7 @@
 
 if _MAC_OS:
     pre_include_bits = ['#define MACOSX']
-else: 
+else:
     pre_include_bits = []
 
 if _FREEBSD or _NETBSD or _WIN32:
@@ -145,15 +145,20 @@
         else:
             return lltype.nullptr(rffi.VOIDP.TO)
 
+    def _dlopen_default_mode():
+        """ The default dlopen mode if it hasn't been changed by the user.
+        """
+        mode = RTLD_NOW
+        if RTLD_LOCAL is not None:
+            mode |= RTLD_LOCAL
+        return mode
+
     def dlopen(name, mode=-1):
         """ Wrapper around C-level dlopen
         """
         if mode == -1:
-            if RTLD_LOCAL is not None:
-                mode = RTLD_LOCAL
-            else:
-                mode = 0
-        if (mode & (RTLD_LAZY | RTLD_NOW)) == 0:
+            mode = _dlopen_default_mode()
+        elif (mode & (RTLD_LAZY | RTLD_NOW)) == 0:
             mode |= RTLD_NOW
         res = c_dlopen(name, rffi.cast(rffi.INT, mode))
         if not res:
@@ -193,6 +198,11 @@
     DLLHANDLE = rwin32.HMODULE
     RTLD_GLOBAL = None
 
+    def _dlopen_default_mode():
+        """ The default dlopen mode if it hasn't been changed by the user.
+        """
+        return 0
+
     def dlopen(name, mode=-1):
         # mode is unused on windows, but a consistant signature
         res = rwin32.LoadLibrary(name)
diff --git a/rpython/rlib/rstring.py b/rpython/rlib/rstring.py
--- a/rpython/rlib/rstring.py
+++ b/rpython/rlib/rstring.py
@@ -291,6 +291,7 @@
     return _search(value, other, start, end, SEARCH_COUNT)
 
 # -------------- substring searching helper ----------------
+# XXX a lot of code duplication with lltypesystem.rstr :-(
 
 SEARCH_COUNT = 0
 SEARCH_FIND = 1
@@ -309,6 +310,8 @@
     if end > len(value):
         end = len(value)
     if start > end:
+        if mode == SEARCH_COUNT:
+            return 0
         return -1
 
     count = 0
@@ -326,6 +329,8 @@
     w = n - m
 
     if w < 0:
+        if mode == SEARCH_COUNT:
+            return 0
         return -1
 
     mlast = m - 1
@@ -570,18 +575,20 @@
 
 class ByteListBuilder(object):
     def __init__(self, init_size=INIT_SIZE):
+        assert init_size >= 0
         self.l = newlist_hint(init_size)
 
     @specialize.argtype(1)
     def append(self, s):
+        l = self.l
         for c in s:
-            self.l.append(c)
+            l.append(c)
 
     @specialize.argtype(1)
     def append_slice(self, s, start, end):
-        assert 0 <= start <= end <= len(s)
-        for c in s[start:end]:
-            self.l.append(c)
+        l = self.l
+        for i in xrange(start, end):
+            l.append(s[i])
 
     def append_multiple_char(self, c, times):
         assert isinstance(c, str)
@@ -589,8 +596,9 @@
 
     def append_charpsize(self, s, size):
         assert size >= 0
+        l = self.l
         for i in xrange(size):
-            self.l.append(s[i])
+            l.append(s[i])
 
     def build(self):
         return self.l
diff --git a/rpython/rlib/rvmprof/src/vmprof_config.h b/rpython/rlib/rvmprof/src/vmprof_config.h
--- a/rpython/rlib/rvmprof/src/vmprof_config.h
+++ b/rpython/rlib/rvmprof/src/vmprof_config.h
@@ -1,10 +1,17 @@
-#define HAVE_SYS_UCONTEXT_H
+#if !defined(__OpenBSD__)
+#  define HAVE_SYS_UCONTEXT_H
+#else
+#  define HAVE_SIGNAL_H
+#endif
+
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
   #ifdef __i386__
     #define PC_FROM_UCONTEXT uc_mcontext.mc_eip
   #else
     #define PC_FROM_UCONTEXT uc_mcontext.mc_rip
   #endif
+#elif defined(__OpenBSD__)
+#define PC_FROM_UCONTEXT sc_rip
 #elif defined( __APPLE__)
   #if ((ULONG_MAX) == (UINT_MAX))
     #define PC_FROM_UCONTEXT uc_mcontext->__ss.__eip
diff --git a/rpython/rlib/rvmprof/src/vmprof_getpc.h b/rpython/rlib/rvmprof/src/vmprof_getpc.h
--- a/rpython/rlib/rvmprof/src/vmprof_getpc.h
+++ b/rpython/rlib/rvmprof/src/vmprof_getpc.h
@@ -65,6 +65,10 @@
 #elif defined(HAVE_CYGWIN_SIGNAL_H)
 #include <cygwin/signal.h>
 typedef ucontext ucontext_t;
+#elif defined(HAVE_SIGNAL_H)
+#include <signal.h>
+#else
+#  error "don't know how to get the pc on this platform"
 #endif
 
 
diff --git a/rpython/rlib/test/test_rarithmetic.py b/rpython/rlib/test/test_rarithmetic.py
--- a/rpython/rlib/test/test_rarithmetic.py
+++ b/rpython/rlib/test/test_rarithmetic.py
@@ -401,10 +401,13 @@
 
 @given(strategies.integers(min_value=0, max_value=sys.maxint),
        strategies.integers(min_value=1, max_value=sys.maxint))
-def test_int_c_div(x, y):
+def test_int_c_div_mod(x, y):
     assert int_c_div(~x, y) == -(abs(~x) // y)
     assert int_c_div( x,-y) == -(x // y)
     assert int_c_div(~x,-y) == +(abs(~x) // y)
+    for x1 in [x, ~x]:
+        for y1 in [y, -y]:
+            assert int_c_div(x1, y1) * y1 + int_c_mod(x1, y1) == x1
 
 # these can't be prebuilt on 32bit
 U1 = r_ulonglong(0x0102030405060708L)
diff --git a/rpython/rlib/test/test_rstring.py b/rpython/rlib/test/test_rstring.py
--- a/rpython/rlib/test/test_rstring.py
+++ b/rpython/rlib/test/test_rstring.py
@@ -231,6 +231,10 @@
     check_search(count, 'one two three', 'e', 0, 1, res=0)
     check_search(count, 'one two three', '', 0, 13, res=14)
 
+    check_search(count, '', 'ab', 0, 0, res=0)
+    check_search(count, 'a', 'ab', 0, 1, res=0)
+    check_search(count, 'ac', 'ab', 0, 2, res=0)
+
 
 class TestTranslates(BaseRtypingTest):
     def test_split_rsplit(self):
diff --git a/rpython/rtyper/annlowlevel.py b/rpython/rtyper/annlowlevel.py
--- a/rpython/rtyper/annlowlevel.py
+++ b/rpython/rtyper/annlowlevel.py
@@ -348,19 +348,30 @@
     _about_ = llhelper
 
     def compute_result_annotation(self, s_F, s_callable):
+        from rpython.annotator.description import FunctionDesc
         assert s_F.is_constant()
-        assert s_callable.is_constant()
+        assert isinstance(s_callable, annmodel.SomePBC)
         F = s_F.const
         FUNC = F.TO
         args_s = [lltype_to_annotation(T) for T in FUNC.ARGS]
-        key = (llhelper, s_callable.const)
-        s_res = self.bookkeeper.emulate_pbc_call(key, s_callable, args_s)
-        assert lltype_to_annotation(FUNC.RESULT).contains(s_res)
+        for desc in s_callable.descriptions:
+            assert isinstance(desc, FunctionDesc)
+            assert desc.pyobj is not None
+            if s_callable.is_constant():
+                assert s_callable.const is desc.pyobj
+            key = (llhelper, desc.pyobj)
+            s_res = self.bookkeeper.emulate_pbc_call(key, s_callable, args_s)
+            assert lltype_to_annotation(FUNC.RESULT).contains(s_res)
         return SomePtr(F)
 
     def specialize_call(self, hop):
         hop.exception_cannot_occur()
-        return hop.args_r[1].get_unique_llfn()
+        if hop.args_s[1].is_constant():
+            return hop.args_r[1].get_unique_llfn()
+        else:
+            F = hop.args_s[0].const
+            assert hop.args_r[1].lowleveltype == F
+            return hop.inputarg(hop.args_r[1], 1)
 
 # ____________________________________________________________
 
diff --git a/rpython/rtyper/rint.py b/rpython/rtyper/rint.py
--- a/rpython/rtyper/rint.py
+++ b/rpython/rtyper/rint.py
@@ -236,11 +236,11 @@
         return _rtype_template(hop, 'mul_ovf')
 
     def rtype_floordiv(_, hop):
-        return _rtype_call_helper(hop, 'floordiv', [ZeroDivisionError])
+        return _rtype_call_helper(hop, 'py_div', [ZeroDivisionError])
     rtype_inplace_floordiv = rtype_floordiv
 
     def rtype_floordiv_ovf(_, hop):
-        return _rtype_call_helper(hop, 'floordiv_ovf', [ZeroDivisionError])
+        return _rtype_call_helper(hop, 'py_div_ovf', [ZeroDivisionError])
 
     # turn 'div' on integers into 'floordiv'
     rtype_div         = rtype_floordiv
@@ -250,11 +250,11 @@
     # 'def rtype_truediv' is delegated to the superclass FloatRepr
 
     def rtype_mod(_, hop):
-        return _rtype_call_helper(hop, 'mod', [ZeroDivisionError])
+        return _rtype_call_helper(hop, 'py_mod', [ZeroDivisionError])
     rtype_inplace_mod = rtype_mod
 
     def rtype_mod_ovf(_, hop):
-        return _rtype_call_helper(hop, 'mod_ovf', [ZeroDivisionError])
+        return _rtype_call_helper(hop, 'py_mod_ovf', [ZeroDivisionError])
 
     def rtype_xor(_, hop):
         return _rtype_template(hop, 'xor')
@@ -319,7 +319,7 @@
     vlist = hop.inputargs(repr, repr2)
     prefix = repr.opprefix
 
-    if '_ovf' in func or func.startswith(('mod', 'floordiv')):
+    if '_ovf' in func or func.startswith(('py_mod', 'py_div')):
         if prefix+func not in ('int_add_ovf', 'int_add_nonneg_ovf',
                                'int_sub_ovf', 'int_mul_ovf'):
             raise TyperError("%r should not be used here any more" % (func,))
@@ -353,7 +353,7 @@
             any_implicit_exception = True
 
     if not any_implicit_exception:
-        if not func.startswith(('mod', 'floordiv')):
+        if not func.startswith(('py_mod', 'py_div')):
             return _rtype_template(hop, func)
 
     repr = hop.r_result
@@ -388,7 +388,7 @@
 # ---------- floordiv ----------
 
 @jit.oopspec("int.py_div(x, y)")
-def ll_int_floordiv(x, y):
+def ll_int_py_div(x, y):
     # Python, and RPython, assume that integer division truncates
     # towards -infinity.  However, in C, integer division truncates
     # towards 0.  So assuming that, we need to apply a correction
@@ -400,159 +400,159 @@
     return r + (u >> INT_BITS_1)
 
 @jit.oopspec("int.py_div(x, y)")
-def ll_int_floordiv_nonnegargs(x, y):
+def ll_int_py_div_nonnegargs(x, y):
     from rpython.rlib.debug import ll_assert
     r = llop.int_floordiv(Signed, x, y)            # <= truncates like in C
-    ll_assert(r >= 0, "int_floordiv_nonnegargs(): one arg is negative")
+    ll_assert(r >= 0, "int_py_div_nonnegargs(): one arg is negative")
     return r
 
-def ll_int_floordiv_zer(x, y):
+def ll_int_py_div_zer(x, y):
     if y == 0:
         raise ZeroDivisionError("integer division")
-    return ll_int_floordiv(x, y)
+    return ll_int_py_div(x, y)
 
-def ll_int_floordiv_ovf(x, y):
+def ll_int_py_div_ovf(x, y):
     # JIT: 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("integer division")
-    return ll_int_floordiv(x, y)
+    return ll_int_py_div(x, y)
 
-def ll_int_floordiv_ovf_zer(x, y):
+def ll_int_py_div_ovf_zer(x, y):
     if y == 0:
         raise ZeroDivisionError("integer division")
-    return ll_int_floordiv_ovf(x, y)
+    return ll_int_py_div_ovf(x, y)
 
 @jit.oopspec("int.udiv(x, y)")
-def ll_uint_floordiv(x, y):
+def ll_uint_py_div(x, y):
     return llop.uint_floordiv(Unsigned, x, y)
 
-def ll_uint_floordiv_zer(x, y):
+def ll_uint_py_div_zer(x, y):
     if y == 0:
         raise ZeroDivisionError("unsigned integer division")
-    return ll_uint_floordiv(x, y)
+    return ll_uint_py_div(x, y)
 
 if SignedLongLong == Signed:
-    ll_llong_floordiv      = ll_int_floordiv
-    ll_llong_floordiv_zer  = ll_int_floordiv_zer
-    ll_ullong_floordiv     = ll_uint_floordiv
-    ll_ullong_floordiv_zer = ll_uint_floordiv_zer
+    ll_llong_py_div      = ll_int_py_div
+    ll_llong_py_div_zer  = ll_int_py_div_zer
+    ll_ullong_py_div     = ll_uint_py_div
+    ll_ullong_py_div_zer = ll_uint_py_div_zer
 else:
     @jit.dont_look_inside
-    def ll_llong_floordiv(x, y):
+    def ll_llong_py_div(x, y):
         r = llop.llong_floordiv(SignedLongLong, x, y)  # <= truncates like in C
         p = r * y
         if y < 0: u = p - x
         else:     u = x - p
         return r + (u >> LLONG_BITS_1)
 
-    def ll_llong_floordiv_zer(x, y):
+    def ll_llong_py_div_zer(x, y):
         if y == 0:
             raise ZeroDivisionError("longlong division")
-        return ll_llong_floordiv(x, y)
+        return ll_llong_py_div(x, y)
 
     @jit.dont_look_inside
-    def ll_ullong_floordiv(x, y):
+    def ll_ullong_py_div(x, y):
         return llop.ullong_floordiv(UnsignedLongLong, x, y)
 
-    def ll_ullong_floordiv_zer(x, y):
+    def ll_ullong_py_div_zer(x, y):
         if y == 0:
             raise ZeroDivisionError("unsigned longlong division")
-        return ll_ullong_floordiv(x, y)
+        return ll_ullong_py_div(x, y)
 
 @jit.dont_look_inside
-def ll_lllong_floordiv(x, y):
+def ll_lllong_py_div(x, y):
     r = llop.lllong_floordiv(SignedLongLongLong, x, y) # <= truncates like in C
     p = r * y
     if y < 0: u = p - x
     else:     u = x - p
     return r + (u >> LLLONG_BITS_1)
 
-def ll_lllong_floordiv_zer(x, y):
+def ll_lllong_py_div_zer(x, y):
     if y == 0:
         raise ZeroDivisionError("longlonglong division")
-    return ll_lllong_floordiv(x, y)
+    return ll_lllong_py_div(x, y)
 
 
 # ---------- mod ----------
 
 @jit.oopspec("int.py_mod(x, y)")
-def ll_int_mod(x, y):
+def ll_int_py_mod(x, y):
     r = llop.int_mod(Signed, x, y)                 # <= truncates like in C
     if y < 0: u = -r
     else:     u = r
     return r + (y & (u >> INT_BITS_1))
 
 @jit.oopspec("int.py_mod(x, y)")
-def ll_int_mod_nonnegargs(x, y):
+def ll_int_py_mod_nonnegargs(x, y):
     from rpython.rlib.debug import ll_assert
     r = llop.int_mod(Signed, x, y)                 # <= truncates like in C
-    ll_assert(r >= 0, "int_mod_nonnegargs(): one arg is negative")
+    ll_assert(r >= 0, "int_py_mod_nonnegargs(): one arg is negative")
     return r
 
-def ll_int_mod_zer(x, y):
+def ll_int_py_mod_zer(x, y):
     if y == 0:
         raise ZeroDivisionError
-    return ll_int_mod(x, y)
+    return ll_int_py_mod(x, y)
 
-def ll_int_mod_ovf(x, y):
-    # see comment in ll_int_floordiv_ovf
+def ll_int_py_mod_ovf(x, y):
+    # see comment in ll_int_py_div_ovf
     if (x == -sys.maxint - 1) & (y == -1):
         raise OverflowError
-    return ll_int_mod(x, y)
+    return ll_int_py_mod(x, y)
 
-def ll_int_mod_ovf_zer(x, y):
+def ll_int_py_mod_ovf_zer(x, y):
     if y == 0:
         raise ZeroDivisionError
-    return ll_int_mod_ovf(x, y)
+    return ll_int_py_mod_ovf(x, y)
 
 @jit.oopspec("int.umod(x, y)")
-def ll_uint_mod(x, y):
+def ll_uint_py_mod(x, y):
     return llop.uint_mod(Unsigned, x, y)
 
-def ll_uint_mod_zer(x, y):
+def ll_uint_py_mod_zer(x, y):
     if y == 0:
         raise ZeroDivisionError
-    return ll_uint_mod(x, y)
+    return ll_uint_py_mod(x, y)
 
 if SignedLongLong == Signed:
-    ll_llong_mod      = ll_int_mod
-    ll_llong_mod_zer  = ll_int_mod_zer
-    ll_ullong_mod     = ll_uint_mod
-    ll_ullong_mod_zer = ll_uint_mod_zer
+    ll_llong_py_mod      = ll_int_py_mod
+    ll_llong_py_mod_zer  = ll_int_py_mod_zer
+    ll_ullong_py_mod     = ll_uint_py_mod
+    ll_ullong_py_mod_zer = ll_uint_py_mod_zer
 else:
     @jit.dont_look_inside
-    def ll_llong_mod(x, y):
+    def ll_llong_py_mod(x, y):
         r = llop.llong_mod(SignedLongLong, x, y)    # <= truncates like in C
         if y < 0: u = -r
         else:     u = r
         return r + (y & (u >> LLONG_BITS_1))
 
-    def ll_llong_mod_zer(x, y):
+    def ll_llong_py_mod_zer(x, y):
         if y == 0:
             raise ZeroDivisionError
-        return ll_llong_mod(x, y)
+        return ll_llong_py_mod(x, y)
 
     @jit.dont_look_inside
-    def ll_ullong_mod(x, y):
+    def ll_ullong_py_mod(x, y):
         return llop.ullong_mod(UnsignedLongLong, x, y)
 
-    def ll_ullong_mod_zer(x, y):
+    def ll_ullong_py_mod_zer(x, y):
         if y == 0:
             raise ZeroDivisionError
         return llop.ullong_mod(UnsignedLongLong, x, y)
 
 @jit.dont_look_inside
-def ll_lllong_mod(x, y):
+def ll_lllong_py_mod(x, y):
     r = llop.lllong_mod(SignedLongLongLong, x, y)  # <= truncates like in C
     if y < 0: u = -r
     else:     u = r
     return r + (y & (u >> LLLONG_BITS_1))
 
-def ll_lllong_mod_zer(x, y):
+def ll_lllong_py_mod_zer(x, y):
     if y == 0:
         raise ZeroDivisionError
-    return ll_lllong_mod(x, y)
+    return ll_lllong_py_mod(x, y)
 
 
 # ---------- lshift, neg, abs ----------
diff --git a/rpython/rtyper/rpbc.py b/rpython/rtyper/rpbc.py
--- a/rpython/rtyper/rpbc.py
+++ b/rpython/rtyper/rpbc.py
@@ -414,7 +414,7 @@
         if self.s_pbc.can_be_None:
             self.descriptions.insert(0, None)
         POINTER_TABLE = Array(self.pointer_repr.lowleveltype,
-                              hints={'nolength': True})
+                              hints={'nolength': True, 'immutable': True})
         pointer_table = malloc(POINTER_TABLE, len(self.descriptions),
                                immortal=True)
         for i, desc in enumerate(self.descriptions):
@@ -564,7 +564,7 @@
     if r_to in r_from._conversion_tables:
         return r_from._conversion_tables[r_to]
     else:
-        t = malloc(Array(Char, hints={'nolength': True}),
+        t = malloc(Array(Char, hints={'nolength': True, 'immutable': True}),
                    len(r_from.descriptions), immortal=True)
         l = []
         for i, d in enumerate(r_from.descriptions):
@@ -577,7 +577,7 @@
         if l == range(len(r_from.descriptions)):
             r = None
         else:
-            r = inputconst(Ptr(Array(Char, hints={'nolength': True})), t)
+            r = inputconst(typeOf(t), t)
         r_from._conversion_tables[r_to] = r
         return r
 
diff --git a/rpython/rtyper/test/test_llann.py b/rpython/rtyper/test/test_llann.py
--- a/rpython/rtyper/test/test_llann.py
+++ b/rpython/rtyper/test/test_llann.py
@@ -462,6 +462,30 @@
     res = interpret(h, [8, 5, 2])
     assert res == 99
 
+def test_llhelper_multiple_functions():
+    S = GcStruct('S', ('x', Signed), ('y', Signed))
+    def f(s):
+        return s.x - s.y
+    def g(s):
+        return s.x + s.y
+
+    F = Ptr(FuncType([Ptr(S)], Signed))
+
+    myfuncs = [f, g]
+
+    def h(x, y, z):
+        s = malloc(S)
+        s.x = x
+        s.y = y
+        fptr = llhelper(F, myfuncs[z])
+        assert typeOf(fptr) == F
+        return fptr(s)
+
+    res = interpret(h, [80, 5, 0])
+    assert res == 75
+    res = interpret(h, [80, 5, 1])
+    assert res == 85
+
 
 def test_cast_instance_to_base_ptr():
     class A:
diff --git a/rpython/rtyper/test/test_rint.py b/rpython/rtyper/test/test_rint.py
--- a/rpython/rtyper/test/test_rint.py
+++ b/rpython/rtyper/test/test_rint.py
@@ -390,7 +390,7 @@
         res = self.interpret(f, [sys.maxint])
         assert res == 0
 
-    def test_int_floordiv_nonnegargs(self):
+    def test_int_py_div_nonnegargs(self):
         def f(x, y):
             assert x >= 0
             assert y >= 0
@@ -398,7 +398,7 @@
         res = self.interpret(f, [1234567, 123])
         assert res == 1234567 // 123
 
-    def test_int_mod_nonnegargs(self):
+    def test_int_py_mod_nonnegargs(self):
         def f(x, y):
             assert x >= 0
             assert y >= 0
diff --git a/rpython/rtyper/test/test_rpbc.py b/rpython/rtyper/test/test_rpbc.py
--- a/rpython/rtyper/test/test_rpbc.py
+++ b/rpython/rtyper/test/test_rpbc.py
@@ -2012,6 +2012,36 @@
         e = py.test.raises(ValueError, self.interpret, f, [3])
         assert str(e.value).startswith(r"exit case '\xff' not found")
 
+    @py.test.mark.parametrize('limit', [3, 5])
+    def test_conversion_table(self, limit):
+        # with limit==3, check conversion from Char to Ptr(Func).
+        # with limit>3, check conversion from Char to Char.
+        def f1():
+            return 111
+        def f2():
+            return 222
+        def f3():
+            return 333
+        def g(n):
+            if n & 1:
+                return f1
+            else:
+                return f2
+        def f(n):
+            x = g(n)    # can be f1 or f2
+            if n > 10:
+                x = f3  # now can be f1 or f2 or f3
+            return x()
+
+        from rpython.config.translationoption import get_combined_translation_config
+        self.config = get_combined_translation_config(translating=True)
+        self.config.translation.withsmallfuncsets = limit
+        assert self.interpret(f, [3]) == 111
+        assert self.interpret(f, [4]) == 222
+        assert self.interpret(f, [13]) == 333
+        assert self.interpret(f, [14]) == 333
+
+
 def test_smallfuncsets_basic():
     from rpython.translator.translator import TranslationContext, graphof
     from rpython.config.translationoption import get_combined_translation_config
diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py
--- a/rpython/rtyper/test/test_rstr.py
+++ b/rpython/rtyper/test/test_rstr.py
@@ -972,6 +972,13 @@
             s.count(s, -10)
         py.test.raises(AnnotatorError, self.interpret, f, ())
 
+    def test_count_in_empty_string(self):
+        const = self.const
+        def fn():
+            return const('').count(const('ab'))
+        res = self.interpret(fn, [])
+        assert res == 0
+
     def test_getitem_exc(self):
         const = self.const
         def f(x):
diff --git a/rpython/translator/sandbox/sandlib.py b/rpython/translator/sandbox/sandlib.py
--- a/rpython/translator/sandbox/sandlib.py
+++ b/rpython/translator/sandbox/sandlib.py
@@ -530,6 +530,9 @@
     def do_ll_os__ll_os_unlink(self, vpathname):
         raise OSError(errno.EPERM, "write access denied")
 
+    def do_ll_os__ll_os_mkdir(self, vpathname, mode=None):
+        raise OSError(errno.EPERM, "write access denied")
+
     def do_ll_os__ll_os_getuid(self):
         return UID
     do_ll_os__ll_os_geteuid = do_ll_os__ll_os_getuid
diff --git a/rpython/translator/test/test_simplify.py b/rpython/translator/test/test_simplify.py
--- a/rpython/translator/test/test_simplify.py
+++ b/rpython/translator/test/test_simplify.py
@@ -55,7 +55,7 @@
     graph, _ = translate(f, [int, int], backend_optimize=False)
     assert len(graph.startblock.operations) == 1
     assert graph.startblock.operations[0].opname == 'direct_call'
-    assert 'int_floordiv_ovf_zer' in repr(
+    assert 'int_py_div_ovf_zer' in repr(
         graph.startblock.operations[0].args[0].value)
     assert len(graph.startblock.exits) == 3
     assert [link.target.operations for link in graph.startblock.exits[1:]] == \
@@ -73,7 +73,7 @@
     graph, _ = translate(f, [int, int], backend_optimize=False)
     assert len(graph.startblock.operations) == 1
     assert graph.startblock.operations[0].opname == 'direct_call'
-    assert 'int_floordiv_ovf_zer' in repr(
+    assert 'int_py_div_ovf_zer' in repr(
         graph.startblock.operations[0].args[0].value)
     assert len(graph.startblock.exits) == 3
     assert [link.target.operations for link in graph.startblock.exits[1:]] == \


More information about the pypy-commit mailing list