Author: Philip Jenvey <[email protected]>
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)
+
[email protected]("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)
+
[email protected]("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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit