Author: Ronan Lamy <ronan.l...@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 -@jit.dont_look_inside -def _int_floordiv(n, m): - return llop.int_floordiv(lltype.Signed, n, m) - -@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:]] == \ _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit