Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r63813:dbaf0bdc00d4 Date: 2013-05-02 17:04 -0700 http://bitbucket.org/pypy/pypy/changeset/dbaf0bdc00d4/
Log: merge default diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-2.0.rst copy from pypy/doc/whatsnew-head.rst copy to pypy/doc/whatsnew-2.0.rst 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 @@ -1,140 +1,8 @@ ====================== -What's new in PyPy 2.0 +What's new in PyPy 2.1 ====================== -.. this is a revision shortly after release-2.0-beta1 -.. startrev: 0e6161a009c6 +.. this is a revision shortly after release-2.0 +.. startrev: a13c07067613 -.. branch: split-rpython -Split rpython and pypy into seperate directories -.. branch: callback-jit -Callbacks from C are now better JITted - -.. branch: fix-jit-logs - -.. branch: remove-globals-in-jit - -.. branch: length-hint -Implement __lenght_hint__ according to PEP 424 - -.. branch: numpypy-longdouble -Long double support for numpypy - -.. branch: numpypy-disable-longdouble -Since r_longdouble support is missing, disable all longdouble and derivative -dtypes using ENABLED_LONG_DOUBLE = False - -.. branch: numpypy-real-as-view -Convert real, imag from ufuncs to views. This involves the beginning of -view() functionality - -.. branch: indexing-by-array -Adds indexing by scalar, adds int conversion from scalar and single element array, -fixes compress, indexing by an array with a smaller shape and the indexed object. - -.. branch: str-dtype-improvement -Allow concatenation of str and numeric arrays - -.. branch: signatures -Improved RPython typing - -.. branch: rpython-bytearray -Rudimentary support for bytearray in RPython - -.. branch: refactor-call_release_gil -Fix a bug which caused cffi to return the wrong result when calling a C -function which calls a Python callback which forces the frames - -.. branch: virtual-raw-mallocs -JIT optimizations which make cffi calls even faster, by removing the need to -allocate a temporary buffer where to store the arguments. - -.. branch: improve-docs-2 -Improve documents and straighten out links - -.. branch: fast-newarray -Inline the fast path of newarray in the assembler. -Disabled on ARM until we fix issues. - -.. branch: reflex-support -Allow dynamic loading of a (Reflex) backend that implements the C-API needed -to provide reflection information - -.. branches we don't care about -.. branch: autoreds -.. branch: kill-faking -.. branch: improved_ebnfparse_error -.. branch: task-decorator -.. branch: fix-e4fa0b2 -.. branch: win32-fixes -.. branch: numpy-unify-methods -.. branch: fix-version-tool -.. branch: popen2-removal -.. branch: pickle-dumps -.. branch: scalar_get_set - -.. branch: release-2.0-beta1 - -.. branch: remove-PYPY_NOT_MAIN_FILE - -.. branch: missing-jit-operations - -.. branch: fix-lookinside-iff-oopspec -Fixed the interaction between two internal tools for controlling the JIT. - -.. branch: inline-virtualref-2 -Better optimized certain types of frame accesses in the JIT, particularly -around exceptions that escape the function they were raised in. - -.. branch: missing-ndarray-attributes -Some missing attributes from ndarrays - -.. branch: cleanup-tests -Consolidated the lib_pypy/pypy_test and pypy/module/test_lib_pypy tests into -one directory for reduced confusion and so they all run nightly. - -.. branch: unquote-faster -.. branch: urlparse-unquote-faster - -.. branch: signal-and-thread -Add "__pypy__.thread.signals_enabled", a context manager. Can be used in a -non-main thread to enable the processing of signal handlers in that thread. - -.. branch: coding-guide-update-rlib-refs -.. branch: rlib-doc-rpython-refs -.. branch: clean-up-remaining-pypy-rlib-refs - -.. branch: enumerate-rstr -Support enumerate() over rstr types. - -.. branch: cleanup-numpypy-namespace -Cleanup _numpypy and numpypy namespaces to more closely resemble numpy. - -.. branch: kill-flowobjspace -Random cleanups to hide FlowObjSpace from public view. - -.. branch: vendor-rename - -.. branch: jitframe-on-heap -Moves optimized JIT frames from stack to heap. As a side effect it enables -stackless to work well with the JIT on PyPy. Also removes a bunch of code from -the GC which fixes cannot find gc roots. - -.. branch: pycon2013-doc-fixes -Documentation fixes after going through the docs at PyCon 2013 sprint. - -.. branch: extregistry-refactor - -.. branch: remove-list-smm -.. branch: bridge-logging -.. branch: curses_cffi -cffi implementation of _curses - -.. branch: sqlite-cffi -cffi implementation of sqlite3 - -.. branch: release-2.0-beta2 -.. branch: unbreak-freebsd - -.. branch: virtualref-virtualizable diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py --- a/pypy/module/imp/importing.py +++ b/pypy/module/imp/importing.py @@ -31,12 +31,8 @@ # PY_CODERESOURCE = 8 IMP_HOOK = 9 -if sys.platform == 'win32': - SO = ".pyd" -else: - SO = ".so" +SO = '.pyd' if _WIN32 else '.so' DEFAULT_SOABI = 'pypy-%d%d' % PYPY_VERSION[:2] -CHECK_FOR_PYW = sys.platform == 'win32' PYC_TAG = 'pypy-%d%d' % PYPY_VERSION[:2] @@ -70,7 +66,7 @@ return PY_SOURCE, ".py", "U" # on Windows, also check for a .pyw file - if CHECK_FOR_PYW: + if _WIN32: pyfile = filepart + ".pyw" if file_exists(pyfile): return PY_SOURCE, ".pyw", "U" diff --git a/rpython/jit/backend/arm/codebuilder.py b/rpython/jit/backend/arm/codebuilder.py --- a/rpython/jit/backend/arm/codebuilder.py +++ b/rpython/jit/backend/arm/codebuilder.py @@ -49,6 +49,70 @@ instr = self._encode_reg_list(cond << 28 | 0x92D << 16, regs) self.write32(instr) + def STM(self, base, regs, write_back=False, cond=cond.AL): + assert len(regs) > 0 + instr = (cond << 28 + | 0x11 << 23 + | (1 if write_back else 0) << 21 + | (base & 0xF) << 16) + instr = self._encode_reg_list(instr, regs) + self.write32(instr) + + def LDM(self, base, regs, write_back=False, cond=cond.AL): + assert len(regs) > 0 + instr = (cond << 28 + | 0x11 << 23 + | (1 if write_back else 0) << 21 + | 1 << 20 + | (base & 0xF) << 16) + instr = self._encode_reg_list(instr, regs) + self.write32(instr) + + def VSTM(self, base, regs, write_back=False, cond=cond.AL): + # encoding T1 + P = 0 + U = 1 + nregs = len(regs) + assert nregs > 0 and nregs <= 16 + freg = regs[0] + D = (freg & 0x10) >> 4 + Dd = (freg & 0xF) + nregs *= 2 + instr = (cond << 28 + | 3 << 26 + | P << 24 + | U << 23 + | D << 22 + | (1 if write_back else 0) << 21 + | (base & 0xF) << 16 + | Dd << 12 + | 0xB << 8 + | nregs) + self.write32(instr) + + def VLDM(self, base, regs, write_back=False, cond=cond.AL): + # encoding T1 + P = 0 + U = 1 + nregs = len(regs) + assert nregs > 0 and nregs <= 16 + freg = regs[0] + D = (freg & 0x10) >> 4 + Dd = (freg & 0xF) + nregs *= 2 + instr = (cond << 28 + | 3 << 26 + | P << 24 + | U << 23 + | D << 22 + | (1 if write_back else 0) << 21 + | 1 << 20 + | (base & 0xF) << 16 + | Dd << 12 + | 0xB << 8 + | nregs) + self.write32(instr) + def VPUSH(self, regs, cond=cond.AL): nregs = len(regs) assert nregs > 0 and nregs <= 16 diff --git a/rpython/jit/backend/arm/test/test_assembler.py b/rpython/jit/backend/arm/test/test_assembler.py --- a/rpython/jit/backend/arm/test/test_assembler.py +++ b/rpython/jit/backend/arm/test/test_assembler.py @@ -6,11 +6,16 @@ from rpython.jit.backend.arm.test.support import run_asm from rpython.jit.backend.detect_cpu import getcpuclass from rpython.jit.metainterp.resoperation import rop +from rpython.jit.codewriter import longlong from rpython.rtyper.annlowlevel import llhelper from rpython.rtyper.lltypesystem import lltype, rffi from rpython.jit.metainterp.history import JitCellToken from rpython.jit.backend.model import CompiledLoopToken +from rpython.rtyper.lltypesystem import lltype, llmemory, rffi +from rpython.rtyper.annlowlevel import llhelper +from rpython.rlib.objectmodel import specialize +from rpython.rlib.debug import ll_assert CPU = getcpuclass() @@ -247,7 +252,91 @@ self.a.mc.ADD_ri(r.sp.value, r.sp.value, 8) self.a.gen_func_epilog() assert run_asm(self.a) == x + + def test_stm(self): + container = lltype.malloc(lltype.Array(lltype.Signed, hints={'nolength': True}), 10, flavor='raw') + self.a.gen_func_prolog() + self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, container)) + for x in range(10): + self.a.mc.gen_load_int(x, x) + self.a.mc.STM(r.ip.value, [x for x in range(10)]) + self.a.gen_func_epilog() + run_asm(self.a) + for x in range(10): + assert container[x] == x + lltype.free(container, flavor='raw') + def test_ldm(self): + container = lltype.malloc(lltype.Array(lltype.Signed, hints={'nolength': True}), 10, flavor='raw') + for x in range(10): + container[x] = x + self.a.gen_func_prolog() + self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, container)) + self.a.mc.LDM(r.ip.value, [x for x in range(10)]) + for x in range(1, 10): + self.a.mc.ADD_rr(0, 0, x) + self.a.gen_func_epilog() + res = run_asm(self.a) + assert res == sum(range(10)) + lltype.free(container, flavor='raw') + + def test_vstm(self): + n = 14 + source_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE, + hints={'nolength': True}), n, flavor='raw') + target_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE, + hints={'nolength': True}), n, flavor='raw') + for x in range(n): + source_container[x] = longlong.getfloatstorage(float("%d.%d" % (x,x))) + self.a.gen_func_prolog() + for x in range(n): + self.a.mc.ADD_ri(r.ip.value, r.ip.value, 8) + self.a.mc.VLDR(n, r.ip.value) + self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, target_container)) + self.a.mc.VSTM(r.ip.value, [x for x in range(n)]) + self.a.gen_func_epilog() + run_asm(self.a) + for d in range(n): + res = longlong.getrealfloat(target_container[0]) == float("%d.%d" % (d,d)) + lltype.free(source_container, flavor='raw') + lltype.free(target_container, flavor='raw') + + def test_vldm(self): + n = 14 + container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE, + hints={'nolength': True}), n, flavor='raw') + for x in range(n): + container[x] = longlong.getfloatstorage(float("%d.%d" % (x,x))) + self.a.gen_func_prolog() + self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, container)) + self.a.mc.VLDM(r.ip.value, [x for x in range(n)]) + for x in range(1, n): + self.a.mc.VADD(0, 0, x) + self.a.mc.VSTR(r.d0.value, r.ip.value) + self.a.gen_func_epilog() + res = run_asm(self.a) + assert longlong.getrealfloat(container[0]) == sum([float("%d.%d" % (d,d)) for d in range(n)]) + lltype.free(container, flavor='raw') + + def test_vstm_vldm_combined(self): + n = 14 + source_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE, + hints={'nolength': True}), n, flavor='raw') + target_container = lltype.malloc(lltype.Array(longlong.FLOATSTORAGE, + hints={'nolength': True}), n, flavor='raw') + for x in range(n): + source_container[x] = longlong.getfloatstorage(float("%d.%d" % (x,x))) + self.a.gen_func_prolog() + self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, source_container)) + self.a.mc.VLDM(r.ip.value, [x for x in range(n)]) + self.a.mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, target_container)) + self.a.mc.VSTM(r.ip.value, [x for x in range(n)]) + self.a.gen_func_epilog() + run_asm(self.a) + for d in range(n): + res = longlong.getrealfloat(target_container[0]) == float("%d.%d" % (d,d)) + lltype.free(source_container, flavor='raw') + lltype.free(target_container, flavor='raw') def callme(inp): i = inp + 10 diff --git a/rpython/jit/backend/arm/test/test_instr_codebuilder.py b/rpython/jit/backend/arm/test/test_instr_codebuilder.py --- a/rpython/jit/backend/arm/test/test_instr_codebuilder.py +++ b/rpython/jit/backend/arm/test/test_instr_codebuilder.py @@ -139,6 +139,22 @@ def test_push_raises_sp(self): assert py.test.raises(AssertionError, 'self.cb.PUSH([r.sp.value])') + def test_stm(self): + self.cb.STM(r.fp.value, [reg.value for reg in r.caller_resp], cond=conditions.AL) + self.assert_equal('STM fp, {r0, r1, r2, r3}') + + def test_ldm(self): + self.cb.LDM(r.fp.value, [reg.value for reg in r.caller_resp], cond=conditions.AL) + self.assert_equal('LDM fp, {r0, r1, r2, r3}') + + def test_vstm(self): + self.cb.VSTM(r.fp.value, [reg.value for reg in r.caller_vfp_resp], cond=conditions.AL) + self.assert_equal('VSTM fp, {d0, d1, d2, d3, d4, d5, d6, d7}') + + def test_vldm(self): + self.cb.VLDM(r.fp.value, [reg.value for reg in r.caller_vfp_resp], cond=conditions.AL) + self.assert_equal('VLDM fp, {d0, d1, d2, d3, d4, d5, d6, d7}') + def test_pop(self): self.cb.POP([reg.value for reg in r.caller_resp], cond=conditions.AL) self.assert_equal('POP {r0, r1, r2, r3}') 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 @@ -1751,7 +1751,7 @@ def rewrite_op_jit_ffi_save_result(self, op): kind = op.args[0].value - assert kind in ('int', 'float') + assert kind in ('int', 'float', 'longlong', 'singlefloat') return SpaceOperation('libffi_save_result_%s' % kind, op.args[1:], None) def rewrite_op_jit_force_virtual(self, op): diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -1351,24 +1351,39 @@ def bhimpl_ll_read_timestamp(): return read_timestamp() - @arguments("cpu", "i", "i", "i") - def bhimpl_libffi_save_result_int(self, cif_description, exchange_buffer, result): - ARRAY = lltype.Ptr(rffi.CArray(lltype.Signed)) - cif_description = self.cast_int_to_ptr(cif_description, CIF_DESCRIPTION_P) - exchange_buffer = self.cast_int_to_ptr(exchange_buffer, rffi.CCHARP) + def _libffi_save_result(self, cif_description, exchange_buffer, result): + ARRAY = lltype.Ptr(rffi.CArray(lltype.typeOf(result))) + cast_int_to_ptr = self.cpu.cast_int_to_ptr + cif_description = cast_int_to_ptr(cif_description, CIF_DESCRIPTION_P) + exchange_buffer = cast_int_to_ptr(exchange_buffer, rffi.CCHARP) # data_out = rffi.ptradd(exchange_buffer, cif_description.exchange_result) rffi.cast(ARRAY, data_out)[0] = result + _libffi_save_result._annspecialcase_ = 'specialize:argtype(3)' - @arguments("cpu", "i", "i", "f") - def bhimpl_libffi_save_result_float(self, cif_description, exchange_buffer, result): + @arguments("self", "i", "i", "i") + def bhimpl_libffi_save_result_int(self, cif_description, + exchange_buffer, result): + self._libffi_save_result(cif_description, exchange_buffer, result) + + @arguments("self", "i", "i", "f") + def bhimpl_libffi_save_result_float(self, cif_description, + exchange_buffer, result): result = longlong.getrealfloat(result) - ARRAY = lltype.Ptr(rffi.CArray(lltype.Float)) - cif_description = self.cast_int_to_ptr(cif_description, CIF_DESCRIPTION_P) - exchange_buffer = self.cast_int_to_ptr(exchange_buffer, rffi.CCHARP) - # - data_out = rffi.ptradd(exchange_buffer, cif_description.exchange_result) - rffi.cast(ARRAY, data_out)[0] = result + self._libffi_save_result(cif_description, exchange_buffer, result) + + @arguments("self", "i", "i", "f") + def bhimpl_libffi_save_result_longlong(self, cif_description, + exchange_buffer, result): + # 32-bit only: 'result' is here a LongLong + assert longlong.is_longlong(lltype.typeOf(result)) + self._libffi_save_result(cif_description, exchange_buffer, result) + + @arguments("self", "i", "i", "i") + def bhimpl_libffi_save_result_singlefloat(self, cif_description, + exchange_buffer, result): + result = longlong.int2singlefloat(result) + self._libffi_save_result(cif_description, exchange_buffer, result) # ---------- diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1190,8 +1190,8 @@ return self.metainterp.execute_and_record(rop.READ_TIMESTAMP, None) @arguments("box", "box", "box") - def opimpl_libffi_save_result_int(self, box_cif_description, box_exchange_buffer, - box_result): + def _opimpl_libffi_save_result(self, box_cif_description, + box_exchange_buffer, box_result): from rpython.rtyper.lltypesystem import llmemory from rpython.rlib.jit_libffi import CIF_DESCRIPTION_P from rpython.jit.backend.llsupport.ffisupport import get_arg_descr @@ -1208,10 +1208,14 @@ assert ofs % itemsize == 0 # alignment check (result) self.metainterp.history.record(rop.SETARRAYITEM_RAW, [box_exchange_buffer, - ConstInt(ofs // itemsize), box_result], + ConstInt(ofs // itemsize), + box_result], None, descr) - opimpl_libffi_save_result_float = opimpl_libffi_save_result_int + opimpl_libffi_save_result_int = _opimpl_libffi_save_result + opimpl_libffi_save_result_float = _opimpl_libffi_save_result + opimpl_libffi_save_result_longlong = _opimpl_libffi_save_result + opimpl_libffi_save_result_singlefloat = _opimpl_libffi_save_result # ------------------------------ diff --git a/rpython/jit/metainterp/test/support.py b/rpython/jit/metainterp/test/support.py --- a/rpython/jit/metainterp/test/support.py +++ b/rpython/jit/metainterp/test/support.py @@ -14,7 +14,10 @@ def _get_jitcodes(testself, CPUClass, func, values, type_system, - supports_longlong=False, translationoptions={}, **kwds): + supports_floats=True, + supports_longlong=False, + supports_singlefloats=False, + translationoptions={}, **kwds): from rpython.jit.codewriter import support class FakeJitCell(object): @@ -67,9 +70,16 @@ cw = codewriter.CodeWriter(cpu, [FakeJitDriverSD()]) cw.debug = True testself.cw = cw + if supports_floats and not cpu.supports_floats: + py.test.skip("this test requires supports_floats=True") + if supports_longlong and not cpu.supports_longlong: + py.test.skip("this test requires supports_longlong=True") + if supports_singlefloats and not cpu.supports_singlefloats: + py.test.skip("this test requires supports_singlefloats=True") policy = JitPolicy() - policy.set_supports_floats(True) + policy.set_supports_floats(supports_floats) policy.set_supports_longlong(supports_longlong) + policy.set_supports_singlefloats(supports_singlefloats) graphs = cw.find_all_graphs(policy) if kwds.get("backendopt"): backend_optimizations(rtyper.annotator.translator, graphs=graphs) diff --git a/rpython/jit/metainterp/test/test_fficall.py b/rpython/jit/metainterp/test/test_fficall.py --- a/rpython/jit/metainterp/test/test_fficall.py +++ b/rpython/jit/metainterp/test/test_fficall.py @@ -5,13 +5,13 @@ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rtyper.annlowlevel import llhelper from rpython.jit.metainterp.test.support import LLJitMixin -from rpython.jit.codewriter.longlong import is_longlong +from rpython.jit.codewriter.longlong import is_longlong, is_64_bit from rpython.rlib import jit from rpython.rlib import jit_libffi from rpython.rlib.jit_libffi import (types, CIF_DESCRIPTION, FFI_TYPE_PP, jit_ffi_call, jit_ffi_save_result) from rpython.rlib.unroll import unrolling_iterable -from rpython.rlib.rarithmetic import intmask, r_longlong +from rpython.rlib.rarithmetic import intmask, r_longlong, r_singlefloat from rpython.rlib.longlong2float import float2longlong def get_description(atypes, rtype): @@ -45,7 +45,12 @@ class FfiCallTests(object): - def _run(self, atypes, rtype, avalues, rvalue, expected_call_release_gil=1): + def _run(self, atypes, rtype, avalues, rvalue, + expected_call_release_gil=1, + supports_floats=True, + supports_longlong=True, + supports_singlefloats=True): + cif_description = get_description(atypes, rtype) def verify(*args): @@ -67,7 +72,11 @@ for avalue in unroll_avalues: TYPE = rffi.CArray(lltype.typeOf(avalue)) data = rffi.ptradd(exchange_buffer, ofs) - assert rffi.cast(lltype.Ptr(TYPE), data)[0] == avalue + got = rffi.cast(lltype.Ptr(TYPE), data)[0] + if lltype.typeOf(avalue) is lltype.SingleFloat: + got = float(got) + avalue = float(avalue) + assert got == avalue ofs += 16 if rvalue is not None: write_rvalue = rvalue @@ -96,17 +105,30 @@ data = rffi.ptradd(exbuf, ofs) res = rffi.cast(lltype.Ptr(TYPE), data)[0] lltype.free(exbuf, flavor='raw') + if lltype.typeOf(res) is lltype.SingleFloat: + res = float(res) return res + def matching_result(res, rvalue): + if rvalue is None: + return res == 654321 + if isinstance(rvalue, r_singlefloat): + rvalue = float(rvalue) + return res == rvalue + with FakeFFI(fake_call_impl_any): res = f() - assert res == rvalue or (res, rvalue) == (654321, None) - res = self.interp_operations(f, []) + assert matching_result(res, rvalue) + res = self.interp_operations(f, [], + supports_floats = supports_floats, + supports_longlong = supports_longlong, + supports_singlefloats = supports_singlefloats) if is_longlong(FUNC.RESULT): - # longlongs are passed around as floats inside the JIT, we - # need to convert it back before checking the value + # longlongs are returned as floats, but that's just + # an inconvenience of interp_operations(). Normally both + # longlong and floats are passed around as longlongs. res = float2longlong(res) - assert res == rvalue or (res, rvalue) == (654321, None) + assert matching_result(res, rvalue) self.check_operations_history(call_may_force=0, call_release_gil=expected_call_release_gil) @@ -119,14 +141,24 @@ [-123456*j for j in range(i)], -42434445) - def test_simple_call_float(self): - self._run([types.double] * 2, types.double, [45.6, 78.9], -4.2) + def test_simple_call_float(self, **kwds): + self._run([types.double] * 2, types.double, [45.6, 78.9], -4.2, **kwds) - def test_simple_call_longlong(self): + def test_simple_call_longlong(self, **kwds): maxint32 = 2147483647 a = r_longlong(maxint32) + 1 b = r_longlong(maxint32) + 2 - self._run([types.slonglong] * 2, types.slonglong, [a, b], a) + self._run([types.slonglong] * 2, types.slonglong, [a, b], a, **kwds) + + def test_simple_call_singlefloat_args(self): + self._run([types.float] * 2, types.double, + [r_singlefloat(10.5), r_singlefloat(31.5)], + -4.5) + + def test_simple_call_singlefloat(self, **kwds): + self._run([types.float] * 2, types.float, + [r_singlefloat(10.5), r_singlefloat(31.5)], + r_singlefloat(-4.5), **kwds) def test_simple_call_longdouble(self): # longdouble is not supported, so we expect NOT to generate a call_release_gil @@ -266,3 +298,20 @@ assert res == math.sin(1.23) lltype.free(atypes, flavor='raw') + + def test_simple_call_float_unsupported(self): + self.test_simple_call_float(supports_floats=False, + expected_call_release_gil=0) + + def test_simple_call_longlong_unsupported(self): + self.test_simple_call_longlong(supports_longlong=False, + expected_call_release_gil=is_64_bit) + + def test_simple_call_singlefloat_unsupported(self): + self.test_simple_call_singlefloat(supports_singlefloats=False, + expected_call_release_gil=0) + + def test_simple_call_float_even_if_other_unsupported(self): + self.test_simple_call_float(supports_longlong=False, + supports_singlefloats=False) + # this is the default: expected_call_release_gil=1 diff --git a/rpython/rlib/jit_libffi.py b/rpython/rlib/jit_libffi.py --- a/rpython/rlib/jit_libffi.py +++ b/rpython/rlib/jit_libffi.py @@ -2,6 +2,7 @@ from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rtyper.extregistry import ExtRegistryEntry from rpython.rlib import clibffi, jit +from rpython.rlib.rarithmetic import r_longlong, r_singlefloat from rpython.rlib.nonconst import NonConstant @@ -107,12 +108,14 @@ reskind = types.getkind(cif_description.rtype) if reskind == 'v': jit_ffi_call_impl_void(cif_description, func_addr, exchange_buffer) - elif reskind == 'f' or reskind == 'L': # L is for longlongs, on 32bit - result = jit_ffi_call_impl_float(cif_description, func_addr, exchange_buffer) - jit_ffi_save_result('float', cif_description, exchange_buffer, result) elif reskind == 'i' or reskind == 'u': - result = jit_ffi_call_impl_int(cif_description, func_addr, exchange_buffer) - jit_ffi_save_result('int', cif_description, exchange_buffer, result) + _do_ffi_call_int(cif_description, func_addr, exchange_buffer) + elif reskind == 'f': + _do_ffi_call_float(cif_description, func_addr, exchange_buffer) + elif reskind == 'L': # L is for longlongs, on 32bit + _do_ffi_call_longlong(cif_description, func_addr, exchange_buffer) + elif reskind == 'S': # SingleFloat + _do_ffi_call_singlefloat(cif_description, func_addr, exchange_buffer) else: # the result kind is not supported: we disable the jit_ffi_call # optimization by calling directly jit_ffi_call_impl_any, so the JIT @@ -123,6 +126,30 @@ jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer) +def _do_ffi_call_int(cif_description, func_addr, exchange_buffer): + result = jit_ffi_call_impl_int(cif_description, func_addr, + exchange_buffer) + jit_ffi_save_result('int', cif_description, exchange_buffer, result) + +def _do_ffi_call_float(cif_description, func_addr, exchange_buffer): + # a separate function in case the backend doesn't support floats + result = jit_ffi_call_impl_float(cif_description, func_addr, + exchange_buffer) + jit_ffi_save_result('float', cif_description, exchange_buffer, result) + +def _do_ffi_call_longlong(cif_description, func_addr, exchange_buffer): + # a separate function in case the backend doesn't support longlongs + result = jit_ffi_call_impl_longlong(cif_description, func_addr, + exchange_buffer) + jit_ffi_save_result('longlong', cif_description, exchange_buffer, result) + +def _do_ffi_call_singlefloat(cif_description, func_addr, exchange_buffer): + # a separate function in case the backend doesn't support singlefloats + result = jit_ffi_call_impl_singlefloat(cif_description, func_addr, + exchange_buffer) + jit_ffi_save_result('singlefloat', cif_description, exchange_buffer,result) + + # we must return a NonConstant else we get the constant -1 as the result of # the flowgraph, and the codewriter does not produce a box for the # result. Note that when not-jitted, the result is unused, but when jitted the @@ -139,6 +166,16 @@ return NonConstant(-1.0) @jit.oopspec("libffi_call(cif_description,func_addr,exchange_buffer)") +def jit_ffi_call_impl_longlong(cif_description, func_addr, exchange_buffer): + jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer) + return r_longlong(-1) + +@jit.oopspec("libffi_call(cif_description,func_addr,exchange_buffer)") +def jit_ffi_call_impl_singlefloat(cif_description, func_addr, exchange_buffer): + jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer) + return r_singlefloat(-1.0) + +@jit.oopspec("libffi_call(cif_description,func_addr,exchange_buffer)") def jit_ffi_call_impl_void(cif_description, func_addr, exchange_buffer): jit_ffi_call_impl_any(cif_description, func_addr, exchange_buffer) return None @@ -175,7 +212,7 @@ def compute_result_annotation(self, kind_s, *args_s): from rpython.annotator import model as annmodel assert isinstance(kind_s, annmodel.SomeString) - assert kind_s.const in ('int', 'float') + assert kind_s.const in ('int', 'float', 'longlong', 'singlefloat') def specialize_call(self, hop): hop.exception_cannot_occur() _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit