Author: David Schneider <[email protected]>
Branch: release-2.0.x
Changeset: r63894:85f4226e0b7a
Date: 2013-05-06 21:44 +0200
http://bitbucket.org/pypy/pypy/changeset/85f4226e0b7a/
Log: merge default
diff --git a/lib_pypy/_ctypes/structure.py b/lib_pypy/_ctypes/structure.py
--- a/lib_pypy/_ctypes/structure.py
+++ b/lib_pypy/_ctypes/structure.py
@@ -167,7 +167,6 @@
return
if '_fields_' not in self.__dict__:
self._fields_ = []
- self._names = []
_set_shape(self, [], self._is_union)
__setattr__ = struct_setattr
diff --git a/lib_pypy/ctypes_config_cache/dumpcache.py
b/lib_pypy/ctypes_config_cache/dumpcache.py
--- a/lib_pypy/ctypes_config_cache/dumpcache.py
+++ b/lib_pypy/ctypes_config_cache/dumpcache.py
@@ -1,25 +1,21 @@
-import os
+import sys, os
from ctypes_configure import dumpcache
-from rpython.jit.backend import detect_cpu
def dumpcache2(basename, config):
- model = detect_cpu.autodetect_main_model_and_size()
- filename = '_%s_%s_.py' % (basename, model)
+ size = 32 if sys.maxint <= 2**32 else 64
+ filename = '_%s_%s_.py' % (basename, size)
dumpcache.dumpcache(__file__, filename, config)
#
filename = os.path.join(os.path.dirname(__file__),
'_%s_cache.py' % (basename,))
g = open(filename, 'w')
print >> g, '''\
-try:
- from __pypy__ import cpumodel
-except ImportError:
- from rpython.jit.backend import detect_cpu
- cpumodel = detect_cpu.autodetect_main_model_and_size()
+import sys
+_size = 32 if sys.maxint <= 2**32 else 64
# XXX relative import, should be removed together with
# XXX the relative imports done e.g. by lib_pypy/pypy_test/test_hashlib
-mod = __import__("_%s_%%s_" %% (cpumodel,),
- globals(), locals(), ["*"])
-globals().update(mod.__dict__)\
+_mod = __import__("_%s_%%s_" %% (_size,),
+ globals(), locals(), ["*"])
+globals().update(_mod.__dict__)\
''' % (basename,)
g.close()
diff --git a/lib_pypy/ctypes_config_cache/rebuild.py
b/lib_pypy/ctypes_config_cache/rebuild.py
--- a/lib_pypy/ctypes_config_cache/rebuild.py
+++ b/lib_pypy/ctypes_config_cache/rebuild.py
@@ -25,13 +25,12 @@
sys.path[:] = path
def try_rebuild():
- from rpython.jit.backend import detect_cpu
- model = detect_cpu.autodetect_main_model_and_size()
- # remove the files '_*_model_.py'
+ size = 32 if sys.maxint <= 2**32 else 64
+ # remove the files '_*_size_.py'
left = {}
for p in os.listdir(_dirpath):
- if p.startswith('_') and (p.endswith('_%s_.py' % model) or
- p.endswith('_%s_.pyc' % model)):
+ if p.startswith('_') and (p.endswith('_%s_.py' % size) or
+ p.endswith('_%s_.pyc' % size)):
os.unlink(os.path.join(_dirpath, p))
elif p.startswith('_') and (p.endswith('_.py') or
p.endswith('_.pyc')):
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -84,6 +84,7 @@
'_multiprocessing': [('objspace.usemodules.rctime', True),
('objspace.usemodules.thread', True)],
'cpyext': [('objspace.usemodules.array', True)],
+ 'cppyy': [('objspace.usemodules.cpyext', True)],
}
module_suggests = {
# the reason you want _rawffi is for ctypes, which
diff --git a/pypy/doc/release-2.0.0.rst b/pypy/doc/release-2.0.0.rst
--- a/pypy/doc/release-2.0.0.rst
+++ b/pypy/doc/release-2.0.0.rst
@@ -3,18 +3,18 @@
============================
We're pleased to announce PyPy 2.0. This is a stable release that brings
-swath of bugfixes, small performance improvements and compatibility fixes.
+a swath of bugfixes, small performance improvements and compatibility fixes.
You can download the PyPy 2.0 release here:
http://pypy.org/download.html
-Two biggest changes since PyPy 1.9 are:
+The two biggest changes since PyPy 1.9 are:
* stackless is now supported including greenlets, which means eventlet
and gevent should work (but read below about gevent)
-* PyPy now contains a release 0.6 of `cffi`_ as a builtin module, which
+* PyPy now contains release 0.6 of `cffi`_ as a builtin module, which
is preferred way of calling C from Python that works well on PyPy
.. _`cffi`: http://cffi.readthedocs.org
@@ -37,17 +37,22 @@
==========
* Stackless including greenlets should work. For gevent, you need to check
- out `pypycore`_ and use `pypy-hacks`_ branch of gevent.
+ out `pypycore`_ and use the `pypy-hacks`_ branch of gevent.
-* cffi is not a module included with PyPy. It's a preferred way of calling
- C from Python that works on PyPy.
+* cffi is now a module included with PyPy. (`cffi`_ also exists for
+ CPython; the two versions should be fully compatible.) It is the
+ preferred way of calling C from Python that works on PyPy.
-* Callbacks from C are now JITted, which means XML parsing is much faster
+* Callbacks from C are now JITted, which means XML parsing is much faster.
* A lot of speed improvements in various language corners, most of them small,
- but speeding up a particular corner a lot
+ but speeding up some particular corners a lot.
-* A lot of stability issues fixed
+* The JIT was refactored to emit machine code which manipulates a "frame"
+ that lives on the heap rather than on the stack. This is what makes
+ Stackless work, and it could bring another future speed-up (not done yet).
+
+* A lot of stability issues fixed.
.. _`pypycore`: https://github.com/gevent-on-pypy/pypycore/
.. _`pypy-hacks`: https://github.com/schmir/gevent/tree/pypy-hacks
diff --git a/pypy/goal/getnightly.py b/pypy/goal/getnightly.py
--- a/pypy/goal/getnightly.py
+++ b/pypy/goal/getnightly.py
@@ -6,8 +6,14 @@
if sys.platform.startswith('linux'):
arch = 'linux'
+ cmd = 'wget "%s"'
+ tar = "tar -x -v --wildcards --strip-components=2 -f %s '*/bin/pypy'"
+if sys.platform.startswith('darwin'):
+ arch = 'osx'
+ cmd = 'curl -O "%s"'
+ tar = "tar -x -v --strip-components=2 -f %s '*/bin/pypy'"
else:
- print 'Cannot determine the platform, please update this scrip'
+ print 'Cannot determine the platform, please update this script'
sys.exit(1)
if sys.maxint == 2**63 - 1:
@@ -23,10 +29,9 @@
tmp = py.path.local.mkdtemp()
mydir = tmp.chdir()
print 'Downloading pypy to', tmp
-if os.system('wget "%s"' % url) != 0:
+if os.system(cmd % url) != 0:
sys.exit(1)
print 'Extracting pypy binary'
mydir.chdir()
-os.system("tar -x -v --wildcards --strip-components=2 -f %s '*/bin/pypy'" %
tmp.join(filename))
-
+os.system(tar % tmp.join(filename))
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -82,6 +82,17 @@
PYC_MAGIC = get_pyc_magic(self.space)
self.extra_interpdef('PYC_MAGIC', 'space.wrap(%d)' % PYC_MAGIC)
#
- from rpython.jit.backend import detect_cpu
- model = detect_cpu.autodetect_main_model_and_size()
- self.extra_interpdef('cpumodel', 'space.wrap(%r)' % model)
+ try:
+ from rpython.jit.backend import detect_cpu
+ model = detect_cpu.autodetect()
+ self.extra_interpdef('cpumodel', 'space.wrap(%r)' % model)
+ except Exception:
+ if self.space.config.translation.jit:
+ raise
+ else:
+ pass # ok fine to ignore in this case
+ #
+ if self.space.config.translation.jit:
+ features = detect_cpu.getcpufeatures(model)
+ self.extra_interpdef('jit_backend_features',
+ 'space.wrap(%r)' % features)
diff --git a/pypy/module/__pypy__/test/test_special.py
b/pypy/module/__pypy__/test/test_special.py
--- a/pypy/module/__pypy__/test/test_special.py
+++ b/pypy/module/__pypy__/test/test_special.py
@@ -62,3 +62,14 @@
assert list_strategy(l) == "empty"
o = 5
raises(TypeError, list_strategy, 5)
+
+
+class AppTestJitFeatures(object):
+ spaceconfig = {"translation.jit": True}
+
+ def test_jit_backend_features(self):
+ from __pypy__ import jit_backend_features
+ supported_types = jit_backend_features
+ assert isinstance(supported_types, list)
+ for x in supported_types:
+ assert x in ['floats', 'singlefloats', 'longlong']
diff --git a/pypy/module/_cffi_backend/misc.py
b/pypy/module/_cffi_backend/misc.py
--- a/pypy/module/_cffi_backend/misc.py
+++ b/pypy/module/_cffi_backend/misc.py
@@ -56,10 +56,15 @@
return rffi.cast(lltype.Unsigned, rffi.cast(TPP, target)[0])
raise NotImplementedError("bad integer size")
[email protected](0)
+def _read_raw_float_data_tp(TPP, target):
+ # in its own function: FLOAT may make the whole function jit-opaque
+ return rffi.cast(lltype.Float, rffi.cast(TPP, target)[0])
+
def read_raw_float_data(target, size):
for TP, TPP in _prim_float_types:
if size == rffi.sizeof(TP):
- return rffi.cast(lltype.Float, rffi.cast(TPP, target)[0])
+ return _read_raw_float_data_tp(TPP, target)
raise NotImplementedError("bad float size")
def read_raw_longdouble_data(target):
@@ -82,10 +87,15 @@
raise NotImplementedError("bad integer size")
[email protected](0, 1)
+def _write_raw_float_data_tp(TP, TPP, target, source):
+ # in its own function: FLOAT may make the whole function jit-opaque
+ rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
+
def write_raw_float_data(target, source, size):
for TP, TPP in _prim_float_types:
if size == rffi.sizeof(TP):
- rffi.cast(TPP, target)[0] = rffi.cast(TP, source)
+ _write_raw_float_data_tp(TP, TPP, target, source)
return
raise NotImplementedError("bad float size")
@@ -263,13 +273,18 @@
# ____________________________________________________________
[email protected](0)
+def _raw_memcopy_tp(TPP, source, dest):
+ # in its own function: LONGLONG may make the whole function jit-opaque
+ rffi.cast(TPP, dest)[0] = rffi.cast(TPP, source)[0]
+
def _raw_memcopy(source, dest, size):
if jit.isconstant(size):
# for the JIT: first handle the case where 'size' is known to be
# a constant equal to 1, 2, 4, 8
for TP, TPP in _prim_unsigned_types:
if size == rffi.sizeof(TP):
- rffi.cast(TPP, dest)[0] = rffi.cast(TPP, source)[0]
+ _raw_memcopy_tp(TPP, source, dest)
return
_raw_memcopy_opaque(source, dest, size)
@@ -283,10 +298,15 @@
llmemory.cast_ptr_to_adr(dest) + zero,
size * llmemory.sizeof(lltype.Char))
[email protected](0, 1)
+def _raw_memclear_tp(TP, TPP, dest):
+ # in its own function: LONGLONG may make the whole function jit-opaque
+ rffi.cast(TPP, dest)[0] = rffi.cast(TP, 0)
+
def _raw_memclear(dest, size):
# for now, only supports the cases of size = 1, 2, 4, 8
for TP, TPP in _prim_unsigned_types:
if size == rffi.sizeof(TP):
- rffi.cast(TPP, dest)[0] = rffi.cast(TP, 0)
+ _raw_memclear_tp(TP, TPP, dest)
return
raise NotImplementedError("bad clear size")
diff --git a/pypy/module/_io/__init__.py b/pypy/module/_io/__init__.py
--- a/pypy/module/_io/__init__.py
+++ b/pypy/module/_io/__init__.py
@@ -38,5 +38,5 @@
def shutdown(self, space):
# at shutdown, flush all open streams. Ignore I/O errors.
- from pypy.module._io.interp_iobase import get_autoflushher
- get_autoflushher(space).flush_all(space)
+ from pypy.module._io.interp_iobase import get_autoflusher
+ get_autoflusher(space).flush_all(space)
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -47,7 +47,7 @@
self.w_dict = space.newdict()
self.__IOBase_closed = False
self.streamholder = None # needed by AutoFlusher
- get_autoflushher(space).add(self)
+ get_autoflusher(space).add(self)
def getdict(self, space):
return self.w_dict
@@ -103,7 +103,7 @@
space.call_method(self, "flush")
finally:
self.__IOBase_closed = True
- get_autoflushher(space).remove(self)
+ get_autoflusher(space).remove(self)
def flush_w(self, space):
if self._CLOSED():
@@ -363,5 +363,5 @@
else:
streamholder.autoflush(space)
-def get_autoflushher(space):
+def get_autoflusher(space):
return space.fromcache(AutoFlusher)
diff --git a/pypy/module/_random/interp_random.py
b/pypy/module/_random/interp_random.py
--- a/pypy/module/_random/interp_random.py
+++ b/pypy/module/_random/interp_random.py
@@ -33,8 +33,8 @@
elif space.isinstance_w(w_n, space.w_long):
w_n = space.abs(w_n)
else:
- # XXX not perfectly like CPython
- w_n = space.abs(space.hash(w_n))
+ n = space.hash_w(w_n)
+ w_n = space.wrap(r_uint(n))
key = []
w_one = space.newint(1)
w_two = space.newint(2)
diff --git a/pypy/module/_random/test/test_random.py
b/pypy/module/_random/test/test_random.py
--- a/pypy/module/_random/test/test_random.py
+++ b/pypy/module/_random/test/test_random.py
@@ -42,13 +42,14 @@
rnd1.setstate((-1, ) * 624 + (0, ))
def test_seed(self):
- import _random
+ import _random, sys
rnd = _random.Random()
rnd.seed()
different_nums = []
+ mask = sys.maxint * 2 + 1
for obj in ["spam and eggs", 3.14, 1+2j, 'a', tuple('abc')]:
nums = []
- for o in [obj, hash(obj), -hash(obj)]:
+ for o in [obj, hash(obj) & mask, -(hash(obj) & mask)]:
rnd.seed(o)
nums.append([rnd.random() for i in range(100)])
n1 = nums[0]
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
@@ -16,6 +16,8 @@
from rpython.rlib.objectmodel import we_are_translated, specialize
from pypy.module.sys.version import PYPY_VERSION
+_WIN32 = sys.platform == 'win32'
+
SEARCH_ERROR = 0
PY_SOURCE = 1
PY_COMPILED = 2
@@ -27,12 +29,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'
@specialize.memo()
def get_so_extension(space):
@@ -64,7 +62,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/pypy/module/pypyjit/test_pypy_c/test_array.py
b/pypy/module/pypyjit/test_pypy_c/test_array.py
--- a/pypy/module/pypyjit/test_pypy_c/test_array.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_array.py
@@ -119,6 +119,12 @@
""")
def test_array_of_floats(self):
+ try:
+ from __pypy__ import jit_backend_features
+ if 'singlefloats' not in jit_backend_features:
+ py.test.skip("test requres singlefloats support from the JIT
backend")
+ except ImportError:
+ pass
def main():
from array import array
img = array('f', [21.5]*1000)
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_structures.py
@@ -230,6 +230,17 @@
pt = POINT(y=2, x=1)
assert (pt.x, pt.y) == (1, 2)
+ def test_subclass_initializer(self):
+ class POINT(Structure):
+ _fields_ = [("x", c_int), ("y", c_int)]
+
+ class POSITION(POINT):
+ # A subclass without _fields_
+ pass
+ pos = POSITION(1, 2)
+ assert (pos.x, pos.y) == (1, 2)
+
+
def test_invalid_field_types(self):
class POINT(Structure):
pass
@@ -538,6 +549,7 @@
raises(AttributeError, setattr, X, "_fields_", [])
Y.__fields__ = []
+
class TestPatologicalCases(BaseCTypesTestChecker):
def test_structure_overloading_getattr(self):
class X(Structure):
diff --git a/pypy/objspace/std/stringobject.py
b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -39,12 +39,10 @@
def unicode_w(w_self, space):
# Use the default encoding.
- from pypy.objspace.std.unicodetype import unicode_from_string, \
- decode_object
+ from pypy.objspace.std.unicodetype import (unicode_from_string,
+ decode_object, _get_encoding_and_errors)
w_defaultencoding = space.call_function(space.sys.get(
'getdefaultencoding'))
- from pypy.objspace.std.unicodetype import _get_encoding_and_errors, \
- unicode_from_string, decode_object
encoding, errors = _get_encoding_and_errors(space, w_defaultencoding,
space.w_None)
if encoding is None and errors is None:
@@ -236,7 +234,7 @@
def str_title__String(space, w_self):
input = w_self._value
builder = StringBuilder(len(input))
- prev_letter=' '
+ prev_letter = ' '
for pos in range(len(input)):
ch = input[pos]
@@ -434,7 +432,7 @@
space.wrap("rjust() argument 2 must be a single character"))
d = u_arg - len(u_self)
- if d>0:
+ if d > 0:
fillchar = fillchar[0] # annotator hint: it's a single character
u_self = d * fillchar + u_self
@@ -450,7 +448,7 @@
space.wrap("ljust() argument 2 must be a single character"))
d = u_arg - len(u_self)
- if d>0:
+ if d > 0:
fillchar = fillchar[0] # annotator hint: it's a single character
u_self += d * fillchar
@@ -471,12 +469,12 @@
return space.newbool(self.find(sub) >= 0)
def str_find__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
- (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
+ (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
res = self.find(w_sub._value, start, end)
return space.wrap(res)
def str_rfind__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
- (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
+ (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
res = self.rfind(w_sub._value, start, end)
return space.wrap(res)
@@ -511,7 +509,7 @@
def str_index__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
- (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
+ (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
res = self.find(w_sub._value, start, end)
if res < 0:
raise OperationError(space.w_ValueError,
@@ -521,7 +519,7 @@
def str_rindex__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
- (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
+ (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
res = self.rfind(w_sub._value, start, end)
if res < 0:
raise OperationError(space.w_ValueError,
@@ -728,7 +726,7 @@
while 1:
#no sophisticated linebreak support now, '\r' just for passing
adapted CPython test
if u_token[offset-1] == "\n" or u_token[offset-1] == "\r":
- break;
+ break
distance += 1
offset -= 1
if offset == 0:
@@ -738,7 +736,7 @@
#print '<offset:%d distance:%d tabsize:%d token:%s>' % (offset,
distance, u_tabsize, u_token)
distance = (u_tabsize-distance) % u_tabsize
if distance == 0:
- distance=u_tabsize
+ distance = u_tabsize
return distance
@@ -760,14 +758,14 @@
for token in split:
#print "%d#%d -%s-" % (_tabindent(oldtoken,u_tabsize), u_tabsize,
token)
- u_expanded += " " * _tabindent(oldtoken,u_tabsize) + token
+ u_expanded += " " * _tabindent(oldtoken, u_tabsize) + token
oldtoken = token
return wrapstr(space, u_expanded)
def str_splitlines__String_ANY(space, w_self, w_keepends):
- u_keepends = space.int_w(w_keepends) # truth value, but type checked
+ u_keepends = space.int_w(w_keepends) # truth value, but type checked
data = w_self._value
selflen = len(data)
strs_w = []
@@ -876,7 +874,6 @@
return wrapchar(space, str[ival])
def getitem__String_Slice(space, w_str, w_slice):
- w = space.wrap
s = w_str._value
length = len(s)
start, stop, step, sl = w_slice.indices4(space, length)
diff --git a/pypy/objspace/std/test/test_listobject.py
b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -948,6 +948,9 @@
def test_setitem_slice_performance(self):
# because of a complexity bug, this used to take forever on a
# translated pypy. On CPython2.6 -A, it takes around 5 seconds.
+ import platform
+ if platform.machine().startswith('arm'):
+ skip("consumes too much memory for most ARM machines")
if self.runappdirect:
count = 16*1024*1024
else:
diff --git a/pypy/pytest-A.py b/pypy/pytest-A.py
--- a/pypy/pytest-A.py
+++ b/pypy/pytest-A.py
@@ -6,6 +6,7 @@
'interpreter/pyparser/test',
'interpreter/test',
'interpreter/test2',
+ 'module/test_lib_pypy',
'objspace/std/test',
],
}
diff --git a/pypy/tool/jitlogparser/test/test_parser.py
b/pypy/tool/jitlogparser/test/test_parser.py
--- a/pypy/tool/jitlogparser/test/test_parser.py
+++ b/pypy/tool/jitlogparser/test/test_parser.py
@@ -4,7 +4,7 @@
parse_log_counts)
from pypy.tool.jitlogparser.storage import LoopStorage
import py, sys
-from rpython.jit.backend.detect_cpu import autodetect_main_model
+from rpython.jit.backend.detect_cpu import autodetect
def parse(input, **kwds):
return SimpleParser.parse_from_input(input, **kwds)
@@ -189,7 +189,7 @@
assert chunk.bytecode_name.startswith('StrLiteralSearch')
def test_parsing_assembler():
- if not autodetect_main_model() == 'x86':
+ if not autodetect().startswith('x86'):
py.test.skip('x86 only test')
backend_dump =
"554889E5534154415541564157488DA500000000488B042590C5540148C7042590C554010000000048898570FFFFFF488B042598C5540148C7042598C554010000000048898568FFFFFF488B0425A0C5540148C70425A0C554010000000048898560FFFFFF488B0425A8C5540148C70425A8C554010000000048898558FFFFFF4C8B3C2550525B0149BB30E06C96FC7F00004D8B334983C60149BB30E06C96FC7F00004D89334981FF102700000F8D000000004983C7014C8B342580F76A024983EE014C89342580F76A024983FE000F8C00000000E9AEFFFFFF488B042588F76A024829E0483B042580EC3C01760D49BB05F30894FC7F000041FFD3554889E5534154415541564157488DA550FFFFFF4889BD70FFFFFF4889B568FFFFFF48899560FFFFFF48898D58FFFFFF4D89C7E954FFFFFF49BB00F00894FC7F000041FFD34440484C3D030300000049BB00F00894FC7F000041FFD34440484C3D070304000000"
dump_start = 0x7f3b0b2e63d5
@@ -218,7 +218,7 @@
assert 'jmp' in loop.operations[-1].asm
def test_parsing_arm_assembler():
- if not autodetect_main_model() == 'arm':
+ if not autodetect().startswith('arm'):
py.test.skip('ARM only test')
backend_dump =
"F04F2DE9108B2DED2CD04DE20DB0A0E17CC302E3DFC040E300409CE5085084E2086000E3006084E504B084E500508CE508D04BE20000A0E10000A0E1B0A10DE30EA044E300A09AE501A08AE2B0910DE30E9044E300A089E5C0910DE30E9044E3009099E5019089E2C0A10DE30EA044E300908AE5010050E1700020E124A092E500C08AE00C90DCE5288000E3090058E10180A0030080A013297000E3090057E10170A0030070A013077088E1200059E30180A0030080A013099049E2050059E30190A0330090A023099088E1000059E30190A0130090A003099087E1000059E3700020E1010080E204200BE5D0210DE30E2044E3002092E5012082E2D0910DE30E9044E3002089E5010050E1700020E100C08AE00C90DCE5282000E3090052E10120A0030020A013297000E3090057E10170A0030070A013077082E1200059E30120A0030020A013099049E2050059E30190A0330090A023099082E1000059E30190A0130090A003099087E1000059E3700020E1010080E20D005BE10FF0A0A1700020E1D8FFFFEA68C100E301C04BE33CFF2FE105010803560000000000000068C100E301C04BE33CFF2FE105010803570000000000000068C100E301C04BE33CFF2FE105014003580000000000000068C100E301C04BE33CFF2FE1050140035900000000000000"
dump_start = int(-0x4ffee930)
@@ -272,7 +272,7 @@
def test_import_log():
- if not autodetect_main_model() == 'x86':
+ if not autodetect().startswith('x86'):
py.test.skip('x86 only test')
_, loops = import_log(str(py.path.local(__file__).join('..',
'logtest.log')))
@@ -281,7 +281,7 @@
assert 'jge' in loops[0].operations[3].asm
def test_import_log_2():
- if not autodetect_main_model() == 'x86':
+ if not autodetect().startswith('x86'):
py.test.skip('x86 only test')
_, loops = import_log(str(py.path.local(__file__).join('..',
'logtest2.log')))
diff --git a/rpython/jit/backend/arm/test/test_fficall.py
b/rpython/jit/backend/arm/test/test_fficall.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/backend/arm/test/test_fficall.py
@@ -0,0 +1,23 @@
+import py
+from rpython.jit.metainterp.test import test_fficall
+from rpython.jit.backend.arm.test.support import JitARMMixin
+
+class TestFfiCall(JitARMMixin, test_fficall.FfiCallTests):
+ # for the individual tests see
+ # ====> ../../../metainterp/test/test_fficall.py
+
+ def _add_libffi_types_to_ll2types_maybe(self):
+ # this is needed by test_guard_not_forced_fails, because it produces a
+ # loop which reads the value of types.* in a variable, then a guard
+ # fail and we switch to blackhole: the problem is that at this point
+ # the blackhole interp has a real integer, but it needs to convert it
+ # back to a lltype pointer (which is handled by ll2ctypes, deeply in
+ # the logic). The workaround is to teach ll2ctypes in advance which
+ # are the addresses of the various types.* structures.
+ # Try to comment this code out and run the test to see how it fails :)
+ from rpython.rtyper.lltypesystem import rffi, lltype, ll2ctypes
+ from rpython.rlib.jit_libffi import types
+ for key, value in types.__dict__.iteritems():
+ if isinstance(value, lltype._ptr):
+ addr = rffi.cast(lltype.Signed, value)
+ ll2ctypes._int2obj[addr] = value
diff --git a/rpython/jit/backend/detect_cpu.py
b/rpython/jit/backend/detect_cpu.py
--- a/rpython/jit/backend/detect_cpu.py
+++ b/rpython/jit/backend/detect_cpu.py
@@ -10,31 +10,31 @@
pass
-def detect_main_model_and_size_from_platform():
+MODEL_X86 = 'x86'
+MODEL_X86_NO_SSE2 = 'x86-without-sse2'
+MODEL_X86_64 = 'x86-64'
+MODEL_ARM = 'arm'
+MODEL_PPC_64 = 'ppc-64'
+# don't use '_' in the model strings; they are replaced by '-'
+
+
+def detect_model_from_c_compiler():
# based on http://sourceforge.net/p/predef/wiki/Architectures/
mapping = {
- ('x86', '64'): [
- '__amd64__', '__amd64', '__x86_64__', '__x86_64', # AMD64
- ],
- ('arm', '32'): ['__arm__', '__thumb__'],
- ('x86', '32'): ['i386', '__i386', '__i386__', '__i686__',],
- ('ppc', '64'): ['__powerpc64__'],
+ MODEL_X86_64: ['__amd64__', '__amd64', '__x86_64__', '__x86_64'],
+ MODEL_ARM: ['__arm__', '__thumb__'],
+ MODEL_X86: ['i386', '__i386', '__i386__', '__i686__'],
+ MODEL_PPC_64: ['__powerpc64__'],
}
for k, v in mapping.iteritems():
for macro in v:
if not getdefined(macro, ''):
continue
- return '_'.join(k)
+ return k
raise ProcessorAutodetectError, "Cannot detect processor using compiler
macros"
-def detect_main_model_from_platform():
- return detect_main_model_and_size_from_platform()[0]
-
-
-def autodetect_main_model():
- if not is_host_build():
- return detect_main_model_from_platform()
+def detect_model_from_host_platform():
mach = None
try:
import platform
@@ -44,67 +44,64 @@
if not mach:
platform = sys.platform.lower()
if platform.startswith('win'): # assume an Intel Windows
- return 'x86'
+ return MODEL_X86
# assume we have 'uname'
mach = os.popen('uname -m', 'r').read().strip()
if not mach:
raise ProcessorAutodetectError, "cannot run 'uname -m'"
- try:
- return {'i386': 'x86',
- 'i486': 'x86',
- 'i586': 'x86',
- 'i686': 'x86',
- 'i86pc': 'x86', # Solaris/Intel
- 'x86': 'x86', # Apple
- 'Power Macintosh': 'ppc',
- 'x86_64': 'x86',
- 'amd64': 'x86', # freebsd
- 'AMD64': 'x86', # win64
- 'armv7l': 'arm',
- 'armv6l': 'arm',
- }[mach]
- except KeyError:
- return mach
+ #
+ result ={'i386': MODEL_X86,
+ 'i486': MODEL_X86,
+ 'i586': MODEL_X86,
+ 'i686': MODEL_X86,
+ 'i86pc': MODEL_X86, # Solaris/Intel
+ 'x86': MODEL_X86, # Apple
+ 'Power Macintosh': MODEL_PPC_64,
+ 'x86_64': MODEL_X86,
+ 'amd64': MODEL_X86, # freebsd
+ 'AMD64': MODEL_X86, # win64
+ 'armv7l': MODEL_ARM,
+ 'armv6l': MODEL_ARM,
+ }[mach]
+ #
+ if result.startswith('x86'):
+ if sys.maxint == 2**63-1:
+ result = MODEL_X86_64
+ else:
+ assert sys.maxint == 2**31-1
+ from rpython.jit.backend.x86.detect_sse2 import detect_sse2
+ if detect_sse2():
+ result = MODEL_X86
+ else:
+ result = MODEL_X86_NO_SSE2
+ #
+ if result.startswith('arm'):
+ from rpython.jit.backend.arm.detect import detect_float
+ assert detect_float(), 'the JIT-compiler requires a vfp unit'
+ #
+ return result
-def autodetect_main_model_and_size():
- if not is_host_build():
- return detect_main_model_and_size_from_platform()
- model = autodetect_main_model()
- if sys.maxint == 2**31-1:
- model += '_32'
- elif sys.maxint == 2**63-1:
- model += '_64'
- else:
- raise AssertionError, "bad value for sys.maxint"
- return model
def autodetect():
- model = autodetect_main_model()
- if sys.maxint == 2**63-1:
- model += '_64'
+ if not is_host_build():
+ return detect_model_from_c_compiler()
else:
- assert sys.maxint == 2**31-1
- if model == 'x86':
- from rpython.jit.backend.x86.detect_sse2 import detect_sse2
- if not detect_sse2():
- model = 'x86-without-sse2'
- if model.startswith('arm'):
- from rpython.jit.backend.arm.detect import detect_hardfloat,
detect_float
- assert detect_float(), 'the JIT-compiler requires a vfp unit'
- return model
+ return detect_model_from_host_platform()
+
def getcpuclassname(backend_name="auto"):
if backend_name == "auto":
backend_name = autodetect()
- if backend_name == 'x86':
+ backend_name = backend_name.replace('_', '-')
+ if backend_name == MODEL_X86:
return "rpython.jit.backend.x86.runner", "CPU"
- elif backend_name == 'x86-without-sse2':
+ elif backend_name == MODEL_X86_NO_SSE2:
return "rpython.jit.backend.x86.runner", "CPU386_NO_SSE2"
- elif backend_name == 'x86_64':
+ elif backend_name == MODEL_X86_64:
return "rpython.jit.backend.x86.runner", "CPU_X86_64"
- elif backend_name == 'cli':
- return "rpython.jit.backend.cli.runner", "CliCPU"
- elif backend_name.startswith('arm'):
+ #elif backend_name == 'cli':
+ # return "rpython.jit.backend.cli.runner", "CliCPU"
+ elif backend_name == MODEL_ARM:
return "rpython.jit.backend.arm.runner", "CPU_ARM"
else:
raise ProcessorAutodetectError, (
@@ -115,6 +112,22 @@
mod = __import__(modname, {}, {}, clsname)
return getattr(mod, clsname)
+
+def getcpufeatures(backend_name="auto"):
+ """NOT_RPYTHON"""
+ cpucls = getcpuclass(backend_name)
+ return [attr[len('supports_'):] for attr in dir(cpucls)
+ if attr.startswith('supports_')
+ and getattr(cpucls, attr)]
+
if __name__ == '__main__':
- print autodetect()
- print getcpuclassname()
+ if len(sys.argv) > 1:
+ name = sys.argv[1]
+ x = name
+ else:
+ name = 'auto'
+ x = autodetect()
+ x = (x, getcpuclassname(name), getcpufeatures(name))
+ print 'autodetect: ', x[0]
+ print 'getcpuclassname:', x[1]
+ print 'getcpufeatures: ', x[2]
diff --git a/rpython/jit/backend/test/runner_test.py
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -18,7 +18,7 @@
from rpython.jit.codewriter import heaptracker, longlong
from rpython.rlib import longlong2float
from rpython.rlib.rarithmetic import intmask, is_valid_int
-from rpython.jit.backend.detect_cpu import autodetect_main_model_and_size
+from rpython.jit.backend.detect_cpu import autodetect
from rpython.jit.backend.llsupport import jitframe
@@ -3539,7 +3539,7 @@
looptoken)
self.cpu.assembler.set_debug(True) # always on untranslated
assert info.asmlen != 0
- cpuname = autodetect_main_model_and_size()
+ cpuname = autodetect()
# XXX we have to check the precise assembler, otherwise
# we don't quite know if borders are correct
diff --git a/rpython/jit/backend/test/test_detect_cpu.py
b/rpython/jit/backend/test/test_detect_cpu.py
--- a/rpython/jit/backend/test/test_detect_cpu.py
+++ b/rpython/jit/backend/test/test_detect_cpu.py
@@ -28,6 +28,13 @@
assert issubclass(cpu, AbstractCPU)
-def test_detect_main_model_and_size_from_platform():
- info = autodetect_main_model_and_size()
- assert detect_main_model_and_size_from_platform() == info
+def test_detect_model_from_c_compiler():
+ info1 = detect_model_from_host_platform()
+ info2 = detect_model_from_c_compiler()
+ assert info1 == info2
+
+def test_getcpufeatures():
+ features = getcpufeatures()
+ assert isinstance(features, list)
+ for x in features:
+ assert x in ['floats', 'singlefloats', 'longlong']
diff --git a/rpython/jit/backend/tool/viewcode.py
b/rpython/jit/backend/tool/viewcode.py
--- a/rpython/jit/backend/tool/viewcode.py
+++ b/rpython/jit/backend/tool/viewcode.py
@@ -50,9 +50,12 @@
def machine_code_dump(data, originaddr, backend_name, label_list=None):
objdump_backend_option = {
'x86': 'i386',
+ 'x86-without-sse2': 'i386',
'x86_32': 'i386',
'x86_64': 'x86-64',
+ 'x86-64': 'x86-64',
'i386': 'i386',
+ 'arm': 'arm',
'arm_32': 'arm',
}
cmd = find_objdump()
diff --git a/rpython/jit/backend/x86/test/conftest.py
b/rpython/jit/backend/x86/test/conftest.py
--- a/rpython/jit/backend/x86/test/conftest.py
+++ b/rpython/jit/backend/x86/test/conftest.py
@@ -3,7 +3,7 @@
cpu = detect_cpu.autodetect()
def pytest_runtest_setup(item):
- if cpu not in ('x86', 'x86_64'):
+ if not cpu.startswith('x86'):
py.test.skip("x86/x86_64 tests skipped: cpu is %r" % (cpu,))
if cpu == 'x86_64':
if os.name == "nt":
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/memory/gctransform/transform.py
b/rpython/memory/gctransform/transform.py
--- a/rpython/memory/gctransform/transform.py
+++ b/rpython/memory/gctransform/transform.py
@@ -281,11 +281,11 @@
def finish_helpers(self, backendopt=True):
if self.translator is not None:
self.mixlevelannotator.finish_annotate()
- self.finished_helpers = True
if self.translator is not None:
self.mixlevelannotator.finish_rtype()
if backendopt:
self.mixlevelannotator.backend_optimize()
+ self.finished_helpers = True
# Make sure that the database also sees all finalizers now.
# It is likely that the finalizers need special support there
newgcdependencies = self.ll_finalizers_ptrs
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()
diff --git a/rpython/translator/c/gcc/test/conftest.py
b/rpython/translator/c/gcc/test/conftest.py
--- a/rpython/translator/c/gcc/test/conftest.py
+++ b/rpython/translator/c/gcc/test/conftest.py
@@ -2,5 +2,5 @@
from rpython.jit.backend import detect_cpu
cpu = detect_cpu.autodetect()
def pytest_runtest_setup(item):
- if cpu not in ('x86', 'x86_64'):
+ if not cpu.startswith('x86'):
py.test.skip("x86 directory skipped: cpu is %r" % (cpu,))
diff --git a/testrunner/runner.py b/testrunner/runner.py
--- a/testrunner/runner.py
+++ b/testrunner/runner.py
@@ -329,7 +329,7 @@
self.collect_one_testdir(testdirs, reldir,
[self.reltoroot(t) for t in entries
if self.is_test_py_file(t)])
- return
+ break
for p1 in entries:
if p1.check(dir=1, link=0):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit