Author: Richard Plangger <r...@pasra.at> Branch: vecopt-merge Changeset: r79435:9add01daf60f Date: 2015-09-04 17:52 +0200 http://bitbucket.org/pypy/pypy/changeset/9add01daf60f/
Log: merged optresult-unroll into vecopt-merge diff too long, truncating to 2000 out of 45372 lines diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -352,8 +352,7 @@ Except when otherwise stated (look for LICENSE files or copyright/license information at the beginning of each file) the files in the 'lib-python/2.7' directory are all copyrighted by the Python Software Foundation and licensed -under the Python Software License of which you can find a copy here: -http://www.python.org/doc/Copyright.html +under the terms that you can find here: https://docs.python.org/2/license.html License for 'pypy/module/unicodedata/' ====================================== @@ -435,4 +434,4 @@ The code is based on gperftools. You may see a copy of the License for it at - https://code.google.com/p/gperftools/source/browse/COPYING + https://github.com/gperftools/gperftools/blob/master/COPYING diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py --- a/_pytest/assertion/rewrite.py +++ b/_pytest/assertion/rewrite.py @@ -308,7 +308,10 @@ if (len(data) != 8 or data[:4] != imp.get_magic() or struct.unpack("<l", data[4:])[0] != mtime): return None - co = marshal.load(fp) + try: + co = marshal.load(fp) + except ValueError: + return None # e.g. bad marshal data because of pypy/cpython mix if not isinstance(co, types.CodeType): # That's interesting.... return None diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO --- a/lib_pypy/cffi.egg-info/PKG-INFO +++ b/lib_pypy/cffi.egg-info/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: cffi -Version: 1.2.0 +Version: 1.2.1 Summary: Foreign Function Interface for Python calling C code. Home-page: http://cffi.readthedocs.org Author: Armin Rigo, Maciej Fijalkowski diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py --- a/lib_pypy/cffi/__init__.py +++ b/lib_pypy/cffi/__init__.py @@ -4,8 +4,8 @@ from .api import FFI, CDefError, FFIError from .ffiplatform import VerificationError, VerificationMissing -__version__ = "1.2.0" -__version_info__ = (1, 2, 0) +__version__ = "1.2.1" +__version_info__ = (1, 2, 1) # The verifier module file names are based on the CRC32 of a string that # contains the following version number. It may be older than __version__ diff --git a/lib_pypy/cffi/_cffi_include.h b/lib_pypy/cffi/_cffi_include.h --- a/lib_pypy/cffi/_cffi_include.h +++ b/lib_pypy/cffi/_cffi_include.h @@ -46,7 +46,7 @@ # endif #else # include <stdint.h> -# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) +# if (defined (__SVR4) && defined (__sun)) || defined(_AIX) || defined(__hpux) # include <alloca.h> # endif #endif diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py --- a/lib_pypy/cffi/cparser.py +++ b/lib_pypy/cffi/cparser.py @@ -15,9 +15,11 @@ except ImportError: lock = None -_r_comment = re.compile(r"/\*.*?\*/|//.*?$", re.DOTALL | re.MULTILINE) -_r_define = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)\s+(.*?)$", - re.MULTILINE) +_r_comment = re.compile(r"/\*.*?\*/|//([^\n\\]|\\.)*?$", + re.DOTALL | re.MULTILINE) +_r_define = re.compile(r"^\s*#\s*define\s+([A-Za-z_][A-Za-z_0-9]*)" + r"\b((?:[^\n\\]|\\.)*?)$", + re.DOTALL | re.MULTILINE) _r_partial_enum = re.compile(r"=\s*\.\.\.\s*[,}]|\.\.\.\s*\}") _r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$") _r_partial_array = re.compile(r"\[\s*\.\.\.\s*\]") @@ -39,6 +41,7 @@ macros = {} for match in _r_define.finditer(csource): macroname, macrovalue = match.groups() + macrovalue = macrovalue.replace('\\\n', '').strip() macros[macroname] = macrovalue csource = _r_define.sub('', csource) # Replace "[...]" with "[__dotdotdotarray__]" @@ -423,13 +426,10 @@ raise api.CDefError( "%s: a function with only '(...)' as argument" " is not correct C" % (funcname or 'in expression')) - elif (len(params) == 1 and - isinstance(params[0].type, pycparser.c_ast.TypeDecl) and - isinstance(params[0].type.type, pycparser.c_ast.IdentifierType) - and list(params[0].type.type.names) == ['void']): - del params[0] args = [self._as_func_arg(self._get_type(argdeclnode.type)) for argdeclnode in params] + if not ellipsis and args == [model.void_type]: + args = [] result = self._get_type(typenode.type) return model.RawFunctionType(tuple(args), result, ellipsis) diff --git a/lib_pypy/cffi/recompiler.py b/lib_pypy/cffi/recompiler.py --- a/lib_pypy/cffi/recompiler.py +++ b/lib_pypy/cffi/recompiler.py @@ -4,11 +4,6 @@ VERSION = "0x2601" -try: - int_type = (int, long) -except NameError: # Python 3 - int_type = int - class GlobalExpr: def __init__(self, name, address, type_op, size=0, check_value=0): diff --git a/lib_pypy/cffi/setuptools_ext.py b/lib_pypy/cffi/setuptools_ext.py --- a/lib_pypy/cffi/setuptools_ext.py +++ b/lib_pypy/cffi/setuptools_ext.py @@ -81,10 +81,16 @@ allsources.extend(kwds.pop('sources', [])) ext = Extension(name=module_name, sources=allsources, **kwds) - def make_mod(tmpdir): + def make_mod(tmpdir, pre_run=None): c_file = os.path.join(tmpdir, module_name + source_extension) log.info("generating cffi module %r" % c_file) mkpath(tmpdir) + # a setuptools-only, API-only hook: called with the "ext" and "ffi" + # arguments just before we turn the ffi into C code. To use it, + # subclass the 'distutils.command.build_ext.build_ext' class and + # add a method 'def pre_run(self, ext, ffi)'. + if pre_run is not None: + pre_run(ext, ffi) updated = recompiler.make_c_source(ffi, module_name, source, c_file) if not updated: log.info("already up-to-date") @@ -98,7 +104,8 @@ class build_ext_make_mod(base_class): def run(self): if ext.sources[0] == '$PLACEHOLDER': - ext.sources[0] = make_mod(self.build_temp) + pre_run = getattr(self, 'pre_run', None) + ext.sources[0] = make_mod(self.build_temp, pre_run) base_class.run(self) dist.cmdclass['build_ext'] = build_ext_make_mod # NB. multiple runs here will create multiple 'build_ext_make_mod' diff --git a/lib_pypy/ctypes_support.py b/lib_pypy/ctypes_support.py --- a/lib_pypy/ctypes_support.py +++ b/lib_pypy/ctypes_support.py @@ -28,7 +28,7 @@ def _where_is_errno(): return standard_c_lib.__errno_location() -elif sys.platform in ('darwin', 'freebsd7', 'freebsd8', 'freebsd9'): +elif sys.platform == 'darwin' or sys.platform.startswith('freebsd'): standard_c_lib.__error.restype = ctypes.POINTER(ctypes.c_int) standard_c_lib.__error.argtypes = None def _where_is_errno(): diff --git a/pypy/doc/embedding.rst b/pypy/doc/embedding.rst --- a/pypy/doc/embedding.rst +++ b/pypy/doc/embedding.rst @@ -46,7 +46,11 @@ source. It'll acquire the GIL. Note: this is meant to be called *only once* or a few times at most. See - the `more complete example`_ below. + the `more complete example`_ below. In PyPy <= 2.6.0, the globals + dictionary is *reused* across multiple calls, giving potentially + strange results (e.g. objects dying too early). In PyPy >= 2.6.1, + you get a new globals dictionary for every call (but then, all globals + dictionaries are all kept alive forever, in ``sys._pypy_execute_source``). .. function:: int pypy_execute_source_ptr(char* source, void* ptr); diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst --- a/pypy/doc/how-to-release.rst +++ b/pypy/doc/how-to-release.rst @@ -31,15 +31,14 @@ and add the new file to pypy/doc/index-of-whatsnew.rst * go to pypy/tool/release and run ``force-builds.py <release branch>`` - The following binaries should be built, however, we need more buildbots - - JIT: windows, linux, os/x, armhf, armel - - no JIT: windows, linux, os/x - - sandbox: linux, os/x + The following JIT binaries should be built, however, we need more buildbots + windows, linux-32, linux-64, osx64, armhf-raring, armhf-raspberrian, armel, + freebsd64 * wait for builds to complete, make sure there are no failures * download the builds, repackage binaries. Tag the release version and download and repackage source from bitbucket. You may find it - convenient to use the ``repackage.sh`` script in pypy/tools to do this. + convenient to use the ``repackage.sh`` script in pypy/tool/release to do this. Otherwise repackage and upload source "-src.tar.bz2" to bitbucket and to cobra, as some packagers prefer a clearly labeled source package diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst --- a/pypy/doc/index-of-whatsnew.rst +++ b/pypy/doc/index-of-whatsnew.rst @@ -7,6 +7,7 @@ .. toctree:: whatsnew-head.rst + whatsnew-2.6.1.rst whatsnew-2.6.0.rst whatsnew-2.5.1.rst whatsnew-2.5.0.rst diff --git a/pypy/doc/whatsnew-2.6.1.rst b/pypy/doc/whatsnew-2.6.1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/whatsnew-2.6.1.rst @@ -0,0 +1,76 @@ +======================== +What's new in PyPy 2.6.1 +======================== + +.. this is a revision shortly after release-2.6.0 +.. startrev: 91904d5c5188 + +.. branch: use_min_scalar +Correctly resolve the output dtype of ufunc(array, scalar) calls. + +.. branch: stdlib-2.7.10 + +Update stdlib to version 2.7.10 + +.. branch: issue2062 + +.. branch: disable-unroll-for-short-loops +The JIT no longer performs loop unrolling if the loop compiles to too much code. + +.. branch: run-create_cffi_imports + +Build cffi import libraries as part of translation by monkey-patching an +additional task into translation + +.. branch: int-float-list-strategy + +Use a compact strategy for Python lists that mix integers and floats, +at least if the integers fit inside 32 bits. These lists are now +stored as an array of floats, like lists that contain only floats; the +difference is that integers are stored as tagged NaNs. (This should +have no visible effect! After ``lst = [42, 42.5]``, the value of +``lst[0]`` is still *not* the float ``42.0`` but the integer ``42``.) + +.. branch: cffi-callback-onerror +Part of cffi 1.2. + +.. branch: cffi-new-allocator +Part of cffi 1.2. + +.. branch: unicode-dtype + +Partial implementation of unicode dtype and unicode scalars. + +.. branch: dtypes-compatability + +Improve compatibility with numpy dtypes; handle offsets to create unions, +fix str() and repr(), allow specifying itemsize, metadata and titles, add flags, +allow subclassing dtype + +.. branch: indexing + +Refactor array indexing to support ellipses. + +.. branch: numpy-docstrings + +Allow the docstrings of built-in numpy objects to be set at run-time. + +.. branch: nditer-revisited + +Implement nditer 'buffered' flag and fix some edge cases + +.. branch: ufunc-reduce + +Allow multiple axes in ufunc.reduce() + +.. branch: fix-tinylang-goals + +Update tinylang goals to match current rpython + +.. branch: vmprof-review + +Clean up of vmprof, notably to handle correctly multiple threads + +.. branch: no_boehm_dl + +Remove extra link library from Boehm GC 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 @@ -2,67 +2,8 @@ What's new in PyPy 2.6+ ======================= -.. this is a revision shortly after release-2.6.0 -.. startrev: 91904d5c5188 - -.. branch: use_min_scalar -Correctly resolve the output dtype of ufunc(array, scalar) calls. - -.. branch: stdlib-2.7.10 - -Update stdlib to version 2.7.10 - -.. branch: issue2062 - -.. branch: disable-unroll-for-short-loops -The JIT no longer performs loop unrolling if the loop compiles to too much code. - -.. branch: run-create_cffi_imports - -Build cffi import libraries as part of translation by monkey-patching an -additional task into translation - -.. branch: int-float-list-strategy - -Use a compact strategy for Python lists that mix integers and floats, -at least if the integers fit inside 32 bits. These lists are now -stored as an array of floats, like lists that contain only floats; the -difference is that integers are stored as tagged NaNs. (This should -have no visible effect! After ``lst = [42, 42.5]``, the value of -``lst[0]`` is still *not* the float ``42.0`` but the integer ``42``.) - -.. branch: cffi-callback-onerror -.. branch: cffi-new-allocator - -.. branch: unicode-dtype - -Partial implementation of unicode dtype and unicode scalars. - -.. branch: dtypes-compatability - -Improve compatibility with numpy dtypes; handle offsets to create unions, -fix str() and repr(), allow specifying itemsize, metadata and titles, add flags, -allow subclassing dtype - -.. branch: indexing - -Refactor array indexing to support ellipses. - -.. branch: numpy-docstrings - -Allow the docstrings of built-in numpy objects to be set at run-time. - -.. branch: nditer-revisited - -Implement nditer 'buffered' flag and fix some edge cases - -.. branch: ufunc-reduce - -Allow multiple axes in ufunc.reduce() - -.. branch: fix-tinylang-goals - -Update tinylang goals to match current rpython +.. this is a revision shortly after release-2.6.1 +.. startrev: 07769be4057b .. branch: vecopt .. branch: vecopt-merge diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py --- a/pypy/goal/targetpypystandalone.py +++ b/pypy/goal/targetpypystandalone.py @@ -128,13 +128,7 @@ @entrypoint('main', [rffi.CCHARP], c_name='pypy_execute_source') def pypy_execute_source(ll_source): - after = rffi.aroundstate.after - if after: after() - source = rffi.charp2str(ll_source) - res = _pypy_execute_source(source) - before = rffi.aroundstate.before - if before: before() - return rffi.cast(rffi.INT, res) + return pypy_execute_source_ptr(ll_source, 0) @entrypoint('main', [rffi.CCHARP, lltype.Signed], c_name='pypy_execute_source_ptr') @@ -142,9 +136,7 @@ after = rffi.aroundstate.after if after: after() source = rffi.charp2str(ll_source) - space.setitem(w_globals, space.wrap('c_argument'), - space.wrap(ll_ptr)) - res = _pypy_execute_source(source) + res = _pypy_execute_source(source, ll_ptr) before = rffi.aroundstate.before if before: before() return rffi.cast(rffi.INT, res) @@ -169,15 +161,21 @@ before = rffi.aroundstate.before if before: before() - w_globals = space.newdict() - space.setitem(w_globals, space.wrap('__builtins__'), - space.builtin_modules['__builtin__']) - - def _pypy_execute_source(source): + def _pypy_execute_source(source, c_argument): try: - compiler = space.createcompiler() - stmt = compiler.compile(source, 'c callback', 'exec', 0) - stmt.exec_code(space, w_globals, w_globals) + w_globals = space.newdict(module=True) + space.setitem(w_globals, space.wrap('__builtins__'), + space.builtin_modules['__builtin__']) + space.setitem(w_globals, space.wrap('c_argument'), + space.wrap(c_argument)) + space.appexec([space.wrap(source), w_globals], """(src, glob): + import sys + stmt = compile(src, 'c callback', 'exec') + if not hasattr(sys, '_pypy_execute_source'): + sys._pypy_execute_source = [] + sys._pypy_execute_source.append(glob) + exec stmt in glob + """) except OperationError, e: debug("OperationError:") debug(" operror-type: " + e.w_type.getname(space)) @@ -343,8 +341,8 @@ def jitpolicy(self, driver): from pypy.module.pypyjit.policy import PyPyJitPolicy - from pypy.module.pypyjit.hooks import pypy_hooks - return PyPyJitPolicy(pypy_hooks) + #from pypy.module.pypyjit.hooks import pypy_hooks + return PyPyJitPolicy()#pypy_hooks) def get_entry_point(self, config): from pypy.tool.lib_pypy import import_from_lib_pypy 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 @@ -62,6 +62,7 @@ } interpleveldefs = { + 'attach_gdb' : 'interp_magic.attach_gdb', 'internal_repr' : 'interp_magic.internal_repr', 'bytebuffer' : 'bytebuffer.bytebuffer', 'identity_dict' : 'interp_identitydict.W_IdentityDict', @@ -100,8 +101,6 @@ def setup_after_space_initialization(self): """NOT_RPYTHON""" - if not self.space.config.translating: - self.extra_interpdef('interp_pdb', 'interp_magic.interp_pdb') if self.space.config.objspace.std.withmethodcachecounter: self.extra_interpdef('method_cache_counter', 'interp_magic.method_cache_counter') @@ -112,18 +111,22 @@ 'interp_magic.mapdict_cache_counter') PYC_MAGIC = get_pyc_magic(self.space) self.extra_interpdef('PYC_MAGIC', 'space.wrap(%d)' % PYC_MAGIC) + # XXX + # the following code prevents --fork-before=pyjitpl from working, + # proper fix would be to use some llop that is only rendered by the + # JIT # - 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 + #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) + #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__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py --- a/pypy/module/__pypy__/interp_magic.py +++ b/pypy/module/__pypy__/interp_magic.py @@ -15,12 +15,10 @@ return space.wrap('%r' % (w_object,)) -def interp_pdb(space): - """Run an interp-level pdb. - This is not available in translated versions of PyPy.""" - assert not we_are_translated() - import pdb - pdb.set_trace() +def attach_gdb(space): + """Run an interp-level gdb (or pdb when untranslated)""" + from rpython.rlib.debug import attach_gdb + attach_gdb() @unwrap_spec(name=str) diff --git a/pypy/module/_cffi_backend/__init__.py b/pypy/module/_cffi_backend/__init__.py --- a/pypy/module/_cffi_backend/__init__.py +++ b/pypy/module/_cffi_backend/__init__.py @@ -2,7 +2,7 @@ from pypy.interpreter.mixedmodule import MixedModule from rpython.rlib import rdynload -VERSION = "1.2.0" +VERSION = "1.2.1" class Module(MixedModule): diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py b/pypy/module/_cffi_backend/test/_backend_test_c.py --- a/pypy/module/_cffi_backend/test/_backend_test_c.py +++ b/pypy/module/_cffi_backend/test/_backend_test_c.py @@ -3427,4 +3427,4 @@ def test_version(): # this test is here mostly for PyPy - assert __version__ == "1.2.0" + assert __version__ == "1.2.1" diff --git a/pypy/module/_multiprocessing/test/test_memory.py b/pypy/module/_multiprocessing/test/test_memory.py --- a/pypy/module/_multiprocessing/test/test_memory.py +++ b/pypy/module/_multiprocessing/test/test_memory.py @@ -1,8 +1,12 @@ +import sys + class AppTestMemory: spaceconfig = dict(usemodules=('_multiprocessing', 'mmap', '_rawffi', 'itertools', - 'signal', 'select', 'fcntl', + 'signal', 'select', 'binascii')) + if sys.platform != 'win32': + spaceconfig['usemodules'] += ('fcntl',) def test_address_of(self): import _multiprocessing diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py --- a/pypy/module/_multiprocessing/test/test_semaphore.py +++ b/pypy/module/_multiprocessing/test/test_semaphore.py @@ -1,12 +1,19 @@ +import sys + from pypy.module._multiprocessing.interp_semaphore import ( RECURSIVE_MUTEX, SEMAPHORE) class AppTestSemaphore: spaceconfig = dict(usemodules=('_multiprocessing', 'thread', - 'signal', 'select', 'fcntl', + 'signal', 'select', 'binascii', 'struct')) + if sys.platform == 'win32': + spaceconfig['usemodules'] += ('_rawffi',) + else: + spaceconfig['usemodules'] += ('fcntl',) + def setup_class(cls): cls.w_SEMAPHORE = cls.space.wrap(SEMAPHORE) cls.w_RECURSIVE = cls.space.wrap(RECURSIVE_MUTEX) diff --git a/pypy/module/_vmprof/__init__.py b/pypy/module/_vmprof/__init__.py --- a/pypy/module/_vmprof/__init__.py +++ b/pypy/module/_vmprof/__init__.py @@ -1,4 +1,5 @@ from pypy.interpreter.mixedmodule import MixedModule +from rpython.rlib.rvmprof import VMProfPlatformUnsupported class Module(MixedModule): """ @@ -19,4 +20,7 @@ # already found by the annotator to be the original empty # method, and the annotator doesn't notice that interp_vmprof.py # (loaded later) replaces this method. -import pypy.module._vmprof.interp_vmprof +try: + import pypy.module._vmprof.interp_vmprof +except VMProfPlatformUnsupported, e: + pass diff --git a/pypy/module/_vmprof/test/test__vmprof.py b/pypy/module/_vmprof/test/test__vmprof.py --- a/pypy/module/_vmprof/test/test__vmprof.py +++ b/pypy/module/_vmprof/test/test__vmprof.py @@ -21,11 +21,12 @@ i = 0 count = 0 i += 5 * WORD # header - assert s[i] == '\x04' - i += 1 # marker - assert s[i] == '\x04' - i += 1 # length - i += len('pypy') + assert s[i ] == '\x05' # MARKER_HEADER + assert s[i + 1] == '\x00' # 0 + assert s[i + 2] == '\x01' # VERSION_THREAD_ID + assert s[i + 3] == chr(4) # len('pypy') + assert s[i + 4: i + 8] == 'pypy' + i += 8 while i < len(s): if s[i] == '\x03': break diff --git a/pypy/module/_vmprof/test/test_direct.py b/pypy/module/_vmprof/test/test_direct.py --- a/pypy/module/_vmprof/test/test_direct.py +++ b/pypy/module/_vmprof/test/test_direct.py @@ -42,7 +42,7 @@ } -""" + open(str(srcdir.join("rvmprof_get_custom_offset.h"))).read()) +""" + open(str(srcdir.join("vmprof_get_custom_offset.h"))).read()) class TestDirect(object): def test_infrastructure(self): diff --git a/pypy/module/cpyext/include/object.h b/pypy/module/cpyext/include/object.h --- a/pypy/module/cpyext/include/object.h +++ b/pypy/module/cpyext/include/object.h @@ -379,6 +379,8 @@ PyObject *ht_name, *ht_slots; } PyHeapTypeObject; +#define PyObject_Bytes PyObject_Str + /* Flag bits for printing: */ #define Py_PRINT_RAW 1 /* No string quotes etc. */ diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py --- a/pypy/module/micronumpy/concrete.py +++ b/pypy/module/micronumpy/concrete.py @@ -52,11 +52,16 @@ @jit.unroll_safe def setslice(self, space, arr): - if len(arr.get_shape()) > 0 and len(self.get_shape()) == 0: - raise oefmt(space.w_ValueError, - "could not broadcast input array from shape " - "(%s) into shape ()", - ','.join([str(x) for x in arr.get_shape()])) + if len(arr.get_shape()) > len(self.get_shape()): + # record arrays get one extra dimension + if not self.dtype.is_record() or \ + len(arr.get_shape()) > len(self.get_shape()) + 1: + raise oefmt(space.w_ValueError, + "could not broadcast input array from shape " + "(%s) into shape (%s)", + ','.join([str(x) for x in arr.get_shape()]), + ','.join([str(x) for x in self.get_shape()]), + ) shape = shape_agreement(space, self.get_shape(), arr) impl = arr.implementation if impl.storage == self.storage: diff --git a/pypy/module/micronumpy/descriptor.py b/pypy/module/micronumpy/descriptor.py --- a/pypy/module/micronumpy/descriptor.py +++ b/pypy/module/micronumpy/descriptor.py @@ -588,7 +588,8 @@ return space.newtuple([w_class, builder_args, data]) def descr_setstate(self, space, w_data): - if self.fields is None: # if builtin dtype + if self.fields is None and not isinstance(self.itemtype, types.VoidType): + # if builtin dtype (but not w_voiddtype) return space.w_None version = space.int_w(space.getitem(w_data, space.wrap(0))) diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py --- a/pypy/module/micronumpy/loop.py +++ b/pypy/module/micronumpy/loop.py @@ -278,6 +278,47 @@ return target +def split_iter(arr, axis_flags): + """Prepare 2 iterators for nested iteration over `arr`. + + Arguments: + arr: instance of BaseConcreteArray + axis_flags: list of bools, one for each dimension of `arr`.The inner + iterator operates over the dimensions for which the flag is True + """ + shape = arr.get_shape() + strides = arr.get_strides() + backstrides = arr.get_backstrides() + shapelen = len(shape) + assert len(axis_flags) == shapelen + inner_shape = [-1] * shapelen + inner_strides = [-1] * shapelen + inner_backstrides = [-1] * shapelen + outer_shape = [-1] * shapelen + outer_strides = [-1] * shapelen + outer_backstrides = [-1] * shapelen + for i in range(len(shape)): + if axis_flags[i]: + inner_shape[i] = shape[i] + inner_strides[i] = strides[i] + inner_backstrides[i] = backstrides[i] + outer_shape[i] = 1 + outer_strides[i] = 0 + outer_backstrides[i] = 0 + else: + outer_shape[i] = shape[i] + outer_strides[i] = strides[i] + outer_backstrides[i] = backstrides[i] + inner_shape[i] = 1 + inner_strides[i] = 0 + inner_backstrides[i] = 0 + inner_iter = ArrayIter(arr, support.product(inner_shape), + inner_shape, inner_strides, inner_backstrides) + outer_iter = ArrayIter(arr, support.product(outer_shape), + outer_shape, outer_strides, outer_backstrides) + return inner_iter, outer_iter + + reduce_flat_driver = jit.JitDriver( name='numpy_reduce_flat', greens = ['shapelen', 'func', 'done_func', 'calc_dtype'], reds = 'auto', @@ -311,34 +352,8 @@ out_iter, out_state = out.create_iter() out_iter.track_index = False shape = w_arr.get_shape() - strides = w_arr.implementation.get_strides() - backstrides = w_arr.implementation.get_backstrides() shapelen = len(shape) - inner_shape = [-1] * shapelen - inner_strides = [-1] * shapelen - inner_backstrides = [-1] * shapelen - outer_shape = [-1] * shapelen - outer_strides = [-1] * shapelen - outer_backstrides = [-1] * shapelen - for i in range(len(shape)): - if axis_flags[i]: - inner_shape[i] = shape[i] - inner_strides[i] = strides[i] - inner_backstrides[i] = backstrides[i] - outer_shape[i] = 1 - outer_strides[i] = 0 - outer_backstrides[i] = 0 - else: - outer_shape[i] = shape[i] - outer_strides[i] = strides[i] - outer_backstrides[i] = backstrides[i] - inner_shape[i] = 1 - inner_strides[i] = 0 - inner_backstrides[i] = 0 - inner_iter = ArrayIter(w_arr.implementation, support.product(inner_shape), - inner_shape, inner_strides, inner_backstrides) - outer_iter = ArrayIter(w_arr.implementation, support.product(outer_shape), - outer_shape, outer_strides, outer_backstrides) + inner_iter, outer_iter = split_iter(w_arr.implementation, axis_flags) assert outer_iter.size == out_iter.size if identity is not None: @@ -491,17 +506,51 @@ arg_driver = jit.JitDriver(name='numpy_' + op_name, greens = ['shapelen', 'dtype'], reds = 'auto') + arg_flat_driver = jit.JitDriver(name='numpy_flat_' + op_name, + greens = ['shapelen', 'dtype'], + reds = 'auto') - def argmin_argmax(arr): + def argmin_argmax(space, w_arr, w_out, axis): + from pypy.module.micronumpy.descriptor import get_dtype_cache + dtype = w_arr.get_dtype() + shapelen = len(w_arr.get_shape()) + axis_flags = [False] * shapelen + axis_flags[axis] = True + inner_iter, outer_iter = split_iter(w_arr.implementation, axis_flags) + outer_state = outer_iter.reset() + out_iter, out_state = w_out.create_iter() + while not outer_iter.done(outer_state): + inner_state = inner_iter.reset() + inner_state.offset = outer_state.offset + cur_best = inner_iter.getitem(inner_state) + inner_state = inner_iter.next(inner_state) + result = 0 + idx = 1 + while not inner_iter.done(inner_state): + arg_driver.jit_merge_point(shapelen=shapelen, dtype=dtype) + w_val = inner_iter.getitem(inner_state) + new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) + if dtype.itemtype.ne(new_best, cur_best): + result = idx + cur_best = new_best + inner_state = inner_iter.next(inner_state) + idx += 1 + result = get_dtype_cache(space).w_longdtype.box(result) + out_iter.setitem(out_state, result) + out_state = out_iter.next(out_state) + outer_state = outer_iter.next(outer_state) + return w_out + + def argmin_argmax_flat(w_arr): result = 0 idx = 1 - dtype = arr.get_dtype() - iter, state = arr.create_iter() + dtype = w_arr.get_dtype() + iter, state = w_arr.create_iter() cur_best = iter.getitem(state) state = iter.next(state) - shapelen = len(arr.get_shape()) + shapelen = len(w_arr.get_shape()) while not iter.done(state): - arg_driver.jit_merge_point(shapelen=shapelen, dtype=dtype) + arg_flat_driver.jit_merge_point(shapelen=shapelen, dtype=dtype) w_val = iter.getitem(state) new_best = getattr(dtype.itemtype, op_name)(cur_best, w_val) if dtype.itemtype.ne(new_best, cur_best): @@ -510,9 +559,10 @@ state = iter.next(state) idx += 1 return result - return argmin_argmax -argmin = _new_argmin_argmax('min') -argmax = _new_argmin_argmax('max') + + return argmin_argmax, argmin_argmax_flat +argmin, argmin_flat = _new_argmin_argmax('min') +argmax, argmax_flat = _new_argmin_argmax('max') dot_driver = jit.JitDriver(name = 'numpy_dot', greens = ['dtype'], diff --git a/pypy/module/micronumpy/ndarray.py b/pypy/module/micronumpy/ndarray.py --- a/pypy/module/micronumpy/ndarray.py +++ b/pypy/module/micronumpy/ndarray.py @@ -23,6 +23,8 @@ get_shape_from_iterable, shape_agreement, shape_agreement_multiple, is_c_contiguous, is_f_contiguous, calc_strides, new_view) from pypy.module.micronumpy.casting import can_cast_array +from pypy.module.micronumpy.descriptor import get_dtype_cache + def _match_dot_shapes(space, left, right): @@ -245,6 +247,20 @@ if space.is_w(w_idx, space.w_Ellipsis): self.implementation.setslice(space, convert_to_array(space, w_value)) return + # TODO: multiarray/mapping.c calls a subclass's __getitem__ here, which + # is a big performance hit but necessary for the matrix class. The original + # C code is like: + #/* + #* WARNING: There is a huge special case here. If this is not a + #* base class array, we have to get the view through its + #* very own index machinery. + #* Many subclasses should probably call __setitem__ + #* with a base class ndarray view to avoid this. + #*/ + #else if (!(index_type & (HAS_FANCY | HAS_SCALAR_ARRAY)) + # && !PyArray_CheckExact(self)) { + #view = (PyArrayObject *)PyObject_GetItem((PyObject *)self, ind); + elif isinstance(w_idx, W_NDimArray) and w_idx.get_dtype().is_bool() \ and w_idx.ndims() > 0: self.setitem_filter(space, w_idx, convert_to_array(space, w_value)) @@ -484,7 +500,7 @@ return self.implementation.swapaxes(space, self, axis1, axis2) def descr_nonzero(self, space): - index_type = descriptor.get_dtype_cache(space).w_int64dtype + index_type = get_dtype_cache(space).w_int64dtype return self.implementation.nonzero(space, index_type) def descr_tolist(self, space): @@ -812,7 +828,7 @@ if self.get_dtype().is_bool(): # numpy promotes bool.round() to float16. Go figure. w_out = W_NDimArray.from_shape(space, self.get_shape(), - descriptor.get_dtype_cache(space).w_float16dtype) + get_dtype_cache(space).w_float16dtype) else: w_out = None elif not isinstance(w_out, W_NDimArray): @@ -820,7 +836,7 @@ "return arrays must be of ArrayType")) out = descriptor.dtype_agreement(space, [self], self.get_shape(), w_out) if out.get_dtype().is_bool() and self.get_dtype().is_bool(): - calc_dtype = descriptor.get_dtype_cache(space).w_longdtype + calc_dtype = get_dtype_cache(space).w_longdtype else: calc_dtype = out.get_dtype() @@ -839,7 +855,7 @@ raise oefmt(space.w_ValueError, "a must be a 1-d array") v = convert_to_array(space, w_v) ret = W_NDimArray.from_shape( - space, v.get_shape(), descriptor.get_dtype_cache(space).w_longdtype) + space, v.get_shape(), get_dtype_cache(space).w_longdtype) if side == NPY.SEARCHLEFT: binsearch = loop.binsearch_left else: @@ -1152,7 +1168,7 @@ def impl(self, space, w_axis=None, w_dtype=None, w_out=None, keepdims=False): out = out_converter(space, w_out) if bool_result: - w_dtype = descriptor.get_dtype_cache(space).w_booldtype + w_dtype = get_dtype_cache(space).w_booldtype return getattr(ufuncs.get(space), ufunc_name).reduce( space, self, w_axis, keepdims, out, w_dtype) impl.__name__ = name @@ -1185,13 +1201,8 @@ def _reduce_argmax_argmin_impl(raw_name): op_name = "arg%s" % raw_name + op_name_flat = "arg%s_flat" % raw_name def impl(self, space, w_axis=None, w_out=None): - if not space.is_none(w_axis): - raise oefmt(space.w_NotImplementedError, - "axis unsupported for %s", op_name) - if not space.is_none(w_out): - raise oefmt(space.w_NotImplementedError, - "out unsupported for %s", op_name) if self.get_size() == 0: raise oefmt(space.w_ValueError, "Can't call %s on zero-size arrays", op_name) @@ -1201,7 +1212,17 @@ raise oefmt(space.w_NotImplementedError, '%s not implemented for %s', op_name, self.get_dtype().get_name()) - return space.wrap(getattr(loop, op_name)(self)) + shape = self.get_shape() + if space.is_none(w_axis) or len(shape) <= 1: + return space.wrap(getattr(loop, op_name_flat)(self)) + else: + axis = space.int_w(w_axis) + assert axis >= 0 + out_shape = shape[:axis] + shape[axis+1:] + dtype = get_dtype_cache(space).w_longdtype + w_out = W_NDimArray.from_shape(space, out_shape, dtype) + return getattr(loop, op_name)(space, self, w_out, axis) + return func_with_new_name(impl, "reduce_%s_impl" % op_name) descr_argmax = _reduce_argmax_argmin_impl("max") diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py --- a/pypy/module/micronumpy/test/test_dtypes.py +++ b/pypy/module/micronumpy/test/test_dtypes.py @@ -350,8 +350,8 @@ assert np.dtype(xyz).name == 'xyz' # another obscure API, used in numpy record.py # it seems numpy throws away the subclass type and parses the spec - a = np.dtype((xyz, [('x', int), ('y', float)])) - assert repr(a) == "dtype([('x', '<i8'), ('y', '<f8')])" + a = np.dtype((xyz, [('x', 'int32'), ('y', 'float32')])) + assert repr(a) == "dtype([('x', '<i4'), ('y', '<f4')])" def test_index(self): import numpy as np diff --git a/pypy/module/micronumpy/test/test_ndarray.py b/pypy/module/micronumpy/test/test_ndarray.py --- a/pypy/module/micronumpy/test/test_ndarray.py +++ b/pypy/module/micronumpy/test/test_ndarray.py @@ -1605,20 +1605,21 @@ assert a.argmax() == 5 assert a.argmax(axis=None, out=None) == 5 assert a[:2, ].argmax() == 3 - import sys - if '__pypy__' in sys.builtin_module_names: - raises(NotImplementedError, a.argmax, axis=0) + assert (a.argmax(axis=0) == array([2, 2])).all() def test_argmin(self): - from numpy import array - a = array([-1.2, 3.4, 5.7, -3.0, 2.7]) + import numpy as np + a = np.array([-1.2, 3.4, 5.7, -3.0, 2.7]) assert a.argmin() == 3 + assert a.argmin(axis=0) == 3 assert a.argmin(axis=None, out=None) == 3 - b = array([]) + b = np.array([]) raises(ValueError, "b.argmin()") - import sys - if '__pypy__' in sys.builtin_module_names: - raises(NotImplementedError, a.argmin, axis=0) + c = np.arange(6).reshape(2, 3) + assert c.argmin() == 0 + assert (c.argmin(axis=0) == np.array([0, 0, 0])).all() + assert (c.argmin(axis=1) == [0, 0]).all() + def test_all(self): from numpy import array @@ -2667,6 +2668,15 @@ a[0, :: -1] = numpy.array([11, 12]) assert (a == [[12, 11], [5, 10]]).all() + a = numpy.zeros((3, 2), int) + b = numpy.ones((3, 1), int) + exc = raises(ValueError, 'a[:, 1] = b') + assert str(exc.value) == "could not broadcast " +\ + "input array from shape (3,1) into shape (3)" + a[:, 1] = b[:,0] > 0.5 + assert (a == [[0, 1], [0, 1], [0, 1]]).all() + + def test_ufunc(self): from numpy import array a = array([[1, 2], [3, 4], [5, 6]]) @@ -2908,14 +2918,14 @@ exc = raises(IndexError, "b[0, 1] = 42") assert str(exc.value) == "unsupported iterator index" assert b.index == 1 - a = array([(False, False, False), - (False, False, False), + a = array([(False, False, False), (False, False, False), - ], + (False, False, False), + ], dtype=[('a', '|b1'), ('b', '|b1'), ('c', '|b1')]) - a.flat = [(True, True, True), - (True, True, True), - (True, True, True)] + a.flat = [(True, True, True), + (True, True, True), + (True, True, True)] assert (a.view(bool) == True).all() def test_flatiter_ops(self): @@ -3807,7 +3817,7 @@ assert (a == [1, 2]).all() def test_pickle(self): - from numpy import dtype, array + from numpy import dtype, array, int32 from cPickle import loads, dumps d = dtype([('x', str), ('y', 'int32')]) @@ -3824,6 +3834,11 @@ assert a[0]['y'] == 2 assert a[1]['y'] == 1 + + a = array([(1, [])], dtype=[('a', int32), ('b', int32, 0)]) + assert a['b'].shape == (1, 0) + b = loads(dumps(a)) + assert b['b'].shape == (1, 0) def test_subarrays(self): from numpy import dtype, array, zeros diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py --- a/pypy/module/micronumpy/test/test_ufuncs.py +++ b/pypy/module/micronumpy/test/test_ufuncs.py @@ -1166,6 +1166,7 @@ assert (logical_xor([True, False, True, False], [1, 2, 0, 0]) == [False, True, True, False]).all() assert (logical_not([True, False]) == [False, True]).all() + assert logical_and.reduce([1.,1.]) == True def test_logn(self): import math diff --git a/pypy/module/micronumpy/ufuncs.py b/pypy/module/micronumpy/ufuncs.py --- a/pypy/module/micronumpy/ufuncs.py +++ b/pypy/module/micronumpy/ufuncs.py @@ -511,15 +511,15 @@ W_Ufunc.__init__(self, name, promote_to_largest, promote_to_float, promote_bools, identity, int_only, allow_bool, allow_complex, complex_to_float) self.func = func - self.bool_result = bool_result if name == 'logical_and': self.done_func = done_if_false elif name == 'logical_or': self.done_func = done_if_true else: self.done_func = None + self.bool_result = bool_result or (self.done_func is not None) self.simple_binary = ( - allow_complex and allow_bool and not bool_result and not int_only + allow_complex and allow_bool and not self.bool_result and not int_only and not complex_to_float and not promote_to_float and not promote_bools) @@ -630,7 +630,7 @@ r_dtype.is_complex())): raise oefmt(space.w_TypeError, "ufunc '%s' not supported for the input types", self.name) - if self.bool_result: + if self.bool_result and not self.done_func: # XXX: should actually pass the arrays dtype = find_result_type(space, [], [l_dtype, r_dtype]) bool_dtype = get_dtype_cache(space).w_booldtype diff --git a/pypy/module/pypyjit/__init__.py b/pypy/module/pypyjit/__init__.py --- a/pypy/module/pypyjit/__init__.py +++ b/pypy/module/pypyjit/__init__.py @@ -8,16 +8,16 @@ 'set_param': 'interp_jit.set_param', 'residual_call': 'interp_jit.residual_call', 'not_from_assembler': 'interp_jit.W_NotFromAssembler', - 'set_compile_hook': 'interp_resop.set_compile_hook', - 'set_optimize_hook': 'interp_resop.set_optimize_hook', - 'set_abort_hook': 'interp_resop.set_abort_hook', - 'get_stats_snapshot': 'interp_resop.get_stats_snapshot', - 'enable_debug': 'interp_resop.enable_debug', - 'disable_debug': 'interp_resop.disable_debug', - 'ResOperation': 'interp_resop.WrappedOp', - 'DebugMergePoint': 'interp_resop.DebugMergePoint', - 'JitLoopInfo': 'interp_resop.W_JitLoopInfo', - 'Box': 'interp_resop.WrappedBox', + #'set_compile_hook': 'interp_resop.set_compile_hook', + #'set_optimize_hook': 'interp_resop.set_optimize_hook', + #'set_abort_hook': 'interp_resop.set_abort_hook', + #'get_stats_snapshot': 'interp_resop.get_stats_snapshot', + #'enable_debug': 'interp_resop.enable_debug', + #'disable_debug': 'interp_resop.disable_debug', + #'ResOperation': 'interp_resop.WrappedOp', + #'DebugMergePoint': 'interp_resop.DebugMergePoint', + #'JitLoopInfo': 'interp_resop.W_JitLoopInfo', + #'Box': 'interp_resop.WrappedBox', 'PARAMETER_DOCS': 'space.wrap(rpython.rlib.jit.PARAMETER_DOCS)', } diff --git a/pypy/module/pypyjit/interp_resop.py b/pypy/module/pypyjit/interp_resop.py --- a/pypy/module/pypyjit/interp_resop.py +++ b/pypy/module/pypyjit/interp_resop.py @@ -8,7 +8,7 @@ from rpython.rtyper.lltypesystem import lltype from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance, hlstr from rpython.rtyper.rclass import OBJECT -from rpython.jit.metainterp.resoperation import rop +#from rpython.jit.metainterp.resoperation import rop from rpython.rlib.nonconst import NonConstant from rpython.rlib import jit_hooks from rpython.rlib.jit import Counters diff --git a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py --- a/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py +++ b/pypy/module/pypyjit/test_pypy_c/test_micronumpy.py @@ -100,43 +100,45 @@ assert len(log.loops) == 1 loop = log._filter(log.loops[0]) assert loop.match(""" - ... - guard_class(p0, #, descr=...) - p4 = getfield_gc_pure(p0, descr=<FieldP pypy.module.micronumpy.iterators.ArrayIter.inst_array \d+>) - i5 = getfield_gc(p2, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset \d+>) + guard_class(p1, #, descr=...) + p4 = getfield_gc_pure(p1, descr=<FieldP pypy.module.micronumpy.iterators.ArrayIter.inst_array \d+>) + i5 = getfield_gc(p0, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset \d+>) p6 = getfield_gc_pure(p4, descr=<FieldP pypy.module.micronumpy.concrete.BaseConcreteArray.inst_dtype \d+>) p7 = getfield_gc_pure(p6, descr=<FieldP pypy.module.micronumpy.descriptor.W_Dtype.inst_itemtype \d+>) guard_class(p7, ConstClass(Float64), descr=...) i9 = getfield_gc_pure(p4, descr=<FieldU pypy.module.micronumpy.concrete.BaseConcreteArray.inst_storage \d+>) - f10 = raw_load(i9, i5, descr=<ArrayF \d+>) - i11 = getfield_gc_pure(p7, descr=<FieldU pypy.module.micronumpy.types.BaseType.inst_native \d+>) - guard_true(i11, descr=...) + i10 = getfield_gc_pure(p6, descr=<FieldU pypy.module.micronumpy.descriptor.W_Dtype.inst_byteorder \d+>) + i12 = int_eq(i10, 61) + i14 = int_eq(i10, 60) + i15 = int_or(i12, i14) + f16 = raw_load(i9, i5, descr=<ArrayF \d+>) + guard_true(i15, descr=...) guard_not_invalidated(descr=...) - i12 = float_ne(f10, 0.0) - guard_true(i12, descr=...) - i15 = getfield_gc_pure(p1, descr=<FieldU pypy.module.micronumpy.boxes.W_BoolBox.inst_value \d+>) - i16 = int_is_true(i15) - guard_false(i16, descr=...) - i20 = getfield_gc(p2, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_index \d+>) - i21 = getfield_gc_pure(p0, descr=<FieldU pypy.module.micronumpy.iterators.ArrayIter.inst_track_index \d+>) - guard_true(i21, descr=...) - i23 = int_add(i20, 1) - p24 = getfield_gc_pure(p2, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst__indices \d+>) - i25 = getfield_gc_pure(p0, descr=<FieldS pypy.module.micronumpy.iterators.ArrayIter.inst_contiguous \d+>) - i26 = int_is_true(i25) - guard_true(i26, descr=...) - i27 = getfield_gc_pure(p6, descr=<FieldS pypy.module.micronumpy.descriptor.W_Dtype.inst_elsize \d+>) - guard_value(i27, 8, descr=...) - i28 = int_add(i5, 8) - i29 = getfield_gc_pure(p0, descr=<FieldS pypy.module.micronumpy.iterators.ArrayIter.inst_size \d+>) - i30 = int_ge(i23, i29) - guard_false(i30, descr=...) - p32 = new_with_vtable(#) + i18 = float_ne(f16, 0.000000) + guard_true(i18, descr=...) + guard_nonnull_class(p2, ConstClass(W_BoolBox), descr=...) + i20 = getfield_gc_pure(p2, descr=<FieldU pypy.module.micronumpy.boxes.W_BoolBox.inst_value \d+>) + i21 = int_is_true(i20) + guard_false(i21, descr=...) + i22 = getfield_gc(p0, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_index \d+>) + i23 = getfield_gc_pure(p1, descr=<FieldU pypy.module.micronumpy.iterators.ArrayIter.inst_track_index \d+>) + guard_true(i23, descr=...) + i25 = int_add(i22, 1) + p26 = getfield_gc_pure(p0, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst__indices \d+>) + i27 = getfield_gc_pure(p1, descr=<FieldS pypy.module.micronumpy.iterators.ArrayIter.inst_contiguous \d+>) + i28 = int_is_true(i27) + guard_true(i28, descr=...) + i29 = getfield_gc_pure(p6, descr=<FieldS pypy.module.micronumpy.descriptor.W_Dtype.inst_elsize \d+>) + i30 = int_add(i5, i29) + i31 = getfield_gc_pure(p1, descr=<FieldS pypy.module.micronumpy.iterators.ArrayIter.inst_size \d+>) + i32 = int_ge(i25, i31) + guard_false(i32, descr=...) + p34 = new_with_vtable(#) {{{ - setfield_gc(p32, i23, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_index \d+>) - setfield_gc(p32, p24, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst__indices \d+>) - setfield_gc(p32, i28, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset \d+>) - setfield_gc(p32, p0, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst_iterator \d+>) + setfield_gc(p34, p1, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst_iterator \d+>) + setfield_gc(p34, i25, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_index \d+>) + setfield_gc(p34, p26, descr=<FieldP pypy.module.micronumpy.iterators.IterState.inst__indices \d+>) + setfield_gc(p34, i30, descr=<FieldS pypy.module.micronumpy.iterators.IterState.inst_offset \d+>) }}} jump(..., descr=...) """) @@ -152,13 +154,12 @@ assert len(log.loops) == 1 loop = log._filter(log.loops[0]) assert loop.match(""" - ... f31 = raw_load(i9, i29, descr=<ArrayF 8>) guard_not_invalidated(descr=...) + i32 = float_ne(f31, 0.000000) + guard_true(i32, descr=...) i34 = getarrayitem_raw(#, #, descr=<ArrayU 1>) # XXX what are these? guard_value(i34, #, descr=...) # XXX don't appear in - i32 = float_ne(f31, 0.000000) - guard_true(i32, descr=...) i35 = getarrayitem_raw(#, #, descr=<ArrayU 1>) # XXX equiv test_zjit i36 = int_add(i24, 1) i37 = int_add(i29, 8) diff --git a/pypy/module/struct/formatiterator.py b/pypy/module/struct/formatiterator.py --- a/pypy/module/struct/formatiterator.py +++ b/pypy/module/struct/formatiterator.py @@ -82,7 +82,13 @@ w_index = space.int(w_obj) # wrapped float -> wrapped int or long if w_index is None: raise StructError("cannot convert argument to integer") - return getattr(space, meth)(w_index) + method = getattr(space, meth) + try: + return method(w_index) + except OperationError as e: + if e.match(self.space, self.space.w_OverflowError): + raise StructError("argument out of range") + raise def accept_bool_arg(self): w_obj = self.accept_obj_arg() diff --git a/pypy/module/struct/test/test_struct.py b/pypy/module/struct/test/test_struct.py --- a/pypy/module/struct/test/test_struct.py +++ b/pypy/module/struct/test/test_struct.py @@ -428,6 +428,9 @@ assert s.unpack(s.pack(42)) == (42,) assert s.unpack_from(memoryview(s.pack(42))) == (42,) + def test_overflow(self): + raises(self.struct.error, self.struct.pack, 'i', 1<<65) + class AppTestStructBuffer(object): spaceconfig = dict(usemodules=['struct', '__pypy__']) diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_parsing.py b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_parsing.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_parsing.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/test_parsing.py @@ -160,6 +160,35 @@ assert func.name == 'sin' assert func.BType == '<func (<double>, <double>), <double>, False>' +def test_remove_line_continuation_comments(): + ffi = FFI(backend=FakeBackend()) + ffi.cdef(""" + double // blah \\ + more comments + x(void); + double // blah\\\\ + y(void); + double // blah\\ \ + etc + z(void); + """) + m = ffi.dlopen(lib_m) + m.x + m.y + m.z + +def test_line_continuation_in_defines(): + ffi = FFI(backend=FakeBackend()) + ffi.cdef(""" + #define ABC\\ + 42 + #define BCD \\ + 43 + """) + m = ffi.dlopen(lib_m) + assert m.ABC == 42 + assert m.BCD == 43 + def test_define_not_supported_for_now(): ffi = FFI(backend=FakeBackend()) e = py.test.raises(CDefError, ffi.cdef, '#define FOO "blah"') @@ -238,6 +267,13 @@ ffi = FFI() ffi.cdef("typedef _Bool bool; void f(bool);") +def test_void_renamed_as_only_arg(): + ffi = FFI() + ffi.cdef("typedef void void_t1;" + "typedef void_t1 void_t;" + "typedef int (*func_t)(void_t);") + assert ffi.typeof("func_t").args == () + def test_win_common_types(): from cffi.commontypes import COMMON_TYPES, _CACHE from cffi.commontypes import win_common_types, resolve_common_type diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_recompiler.py @@ -25,6 +25,9 @@ if 1: # test the .cpp mode too kwds.setdefault('source_extension', '.cpp') source = 'extern "C" {\n%s\n}' % (source,) + else: + kwds['extra_compile_args'] = (kwds.get('extra_compile_args', []) + + ['-Werror']) return recompiler._verify(ffi, module_name, source, *args, **kwds) diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py --- a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py +++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_zdist.py @@ -318,15 +318,32 @@ import cffi ffi = cffi.FFI() ffi.set_source("pack3.mymod", "/*code would be here*/") + ffi._hi_there = 42 """) with open("setup.py", "w") as f: - f.write("""if 1: + f.write("from __future__ import print_function\n" + """if 1: from setuptools import setup + from distutils.command.build_ext import build_ext + import os + + class TestBuildExt(build_ext): + def pre_run(self, ext, ffi): + print('_make_setuptools_api: in pre_run:', end=" ") + assert ffi._hi_there == 42 + assert ext.name == "pack3.mymod" + fn = os.path.join(os.path.dirname(self.build_lib), + '..', 'see_me') + print('creating %r' % (fn,)) + open(fn, 'w').close() + setup(name='example1', version='0.1', packages=['pack3'], package_dir={'': 'src1'}, - cffi_modules=["src1/pack3/_build.py:ffi"]) + cffi_modules=["src1/pack3/_build.py:ffi"], + cmdclass={'build_ext': TestBuildExt}, + ) """) @chdir_to_tmp @@ -335,6 +352,7 @@ self.run(["setup.py", "build"]) self.check_produced_files({'setup.py': None, 'build': '?', + 'see_me': None, 'src1': {'pack3': {'__init__.py': None, '_build.py': None}}}) @@ -344,6 +362,7 @@ self.run(["setup.py", "build_ext", "-i"]) self.check_produced_files({'setup.py': None, 'build': '?', + 'see_me': None, 'src1': {'pack3': {'__init__.py': None, '_build.py': None, 'mymod.SO': None}}}) diff --git a/pypy/module/thread/test/test_lock.py b/pypy/module/thread/test/test_lock.py --- a/pypy/module/thread/test/test_lock.py +++ b/pypy/module/thread/test/test_lock.py @@ -116,9 +116,6 @@ class AppTestLockSignals(GenericTestThread): pytestmark = py.test.mark.skipif("os.name != 'posix'") - def setup_class(cls): - cls.w_using_pthread_cond = cls.space.wrap(sys.platform == 'freebsd6') - def w_acquire_retries_on_intr(self, lock): import thread, os, signal, time self.sig_recvd = False @@ -157,8 +154,6 @@ raise KeyboardInterrupt def test_lock_acquire_interruption(self): - if self.using_pthread_cond: - skip('POSIX condition variables cannot be interrupted') import thread, signal, time # Mimic receiving a SIGINT (KeyboardInterrupt) with SIGALRM while stuck # in a deadlock. diff --git a/pypy/objspace/std/boolobject.py b/pypy/objspace/std/boolobject.py --- a/pypy/objspace/std/boolobject.py +++ b/pypy/objspace/std/boolobject.py @@ -13,7 +13,7 @@ class W_BoolObject(W_IntObject): def __init__(self, boolval): - self.intval = not not boolval + self.intval = int(not not boolval) def __nonzero__(self): raise Exception("you cannot do that, you must use space.is_true()") diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py --- a/pypy/objspace/std/intobject.py +++ b/pypy/objspace/std/intobject.py @@ -309,17 +309,17 @@ def __init__(self, intval): assert is_valid_int(intval) - self.intval = intval + self.intval = int(intval) def __repr__(self): """representation for debugging purposes""" return "%s(%d)" % (self.__class__.__name__, self.intval) def int_w(self, space, allow_conversion=True): - return int(self.intval) + return self.intval def _int_w(self, space): - return int(self.intval) + return self.intval unwrap = _int_w diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py --- a/pypy/objspace/std/mapdict.py +++ b/pypy/objspace/std/mapdict.py @@ -539,17 +539,19 @@ rangen = unroll.unrolling_iterable(range(n)) nmin1 = n - 1 rangenmin1 = unroll.unrolling_iterable(range(nmin1)) + valnmin1 = "_value%s" % nmin1 class subcls(BaseMapdictObject, supercls): def _init_empty(self, map): - for i in rangen: - setattr(self, "_value%s" % i, erase_item(None)) + for i in rangenmin1: + setattr(self, "_value%s" % i, None) + setattr(self, valnmin1, erase_item(None)) self.map = map def _has_storage_list(self): return self.map.length() > n def _mapdict_get_storage_list(self): - erased = getattr(self, "_value%s" % nmin1) + erased = getattr(self, valnmin1) return unerase_list(erased) def _mapdict_read_storage(self, storageindex): @@ -557,23 +559,21 @@ if storageindex < nmin1: for i in rangenmin1: if storageindex == i: - erased = getattr(self, "_value%s" % i) - return unerase_item(erased) + return getattr(self, "_value%s" % i) if self._has_storage_list(): return self._mapdict_get_storage_list()[storageindex - nmin1] erased = getattr(self, "_value%s" % nmin1) return unerase_item(erased) def _mapdict_write_storage(self, storageindex, value): - erased = erase_item(value) for i in rangenmin1: if storageindex == i: - setattr(self, "_value%s" % i, erased) + setattr(self, "_value%s" % i, value) return if self._has_storage_list(): self._mapdict_get_storage_list()[storageindex - nmin1] = value return - setattr(self, "_value%s" % nmin1, erased) + setattr(self, "_value%s" % nmin1, erase_item(value)) def _mapdict_storage_length(self): if self._has_storage_list(): @@ -585,9 +585,9 @@ len_storage = len(storage) for i in rangenmin1: if i < len_storage: - erased = erase_item(storage[i]) + erased = storage[i] else: - erased = erase_item(None) + erased = None setattr(self, "_value%s" % i, erased) has_storage_list = self._has_storage_list() if len_storage < n: diff --git a/pypy/objspace/std/stringmethods.py b/pypy/objspace/std/stringmethods.py --- a/pypy/objspace/std/stringmethods.py +++ b/pypy/objspace/std/stringmethods.py @@ -195,7 +195,8 @@ splitted = split(value, self._chr('\t')) try: - ovfcheck(len(splitted) * tabsize) + if tabsize > 0: + ovfcheck(len(splitted) * tabsize) except OverflowError: raise oefmt(space.w_OverflowError, "new string is too long") expanded = oldtoken = splitted.pop(0) @@ -210,6 +211,8 @@ def _tabindent(self, token, tabsize): """calculates distance behind the token to the next tabstop""" + if tabsize <= 0: + return 0 distance = tabsize if token: distance = 0 diff --git a/pypy/objspace/std/test/test_boolobject.py b/pypy/objspace/std/test/test_boolobject.py --- a/pypy/objspace/std/test/test_boolobject.py +++ b/pypy/objspace/std/test/test_boolobject.py @@ -4,6 +4,10 @@ self.false = self.space.w_False self.wrap = self.space.wrap + def test_init(self): + assert (self.false.intval, type(self.false.intval)) == (0, int) + assert (self.true.intval, type(self.true.intval)) == (1, int) + def test_repr(self): assert self.space.eq_w(self.space.repr(self.true), self.wrap("True")) assert self.space.eq_w(self.space.repr(self.false), self.wrap("False")) diff --git a/pypy/objspace/std/test/test_bytesobject.py b/pypy/objspace/std/test/test_bytesobject.py --- a/pypy/objspace/std/test/test_bytesobject.py +++ b/pypy/objspace/std/test/test_bytesobject.py @@ -388,6 +388,10 @@ skip("Wrong platform") raises((MemoryError, OverflowError), 't\tt\t'.expandtabs, sys.maxint) + def test_expandtabs_0(self): + assert 'x\ty'.expandtabs(0) == 'xy' + assert 'x\ty'.expandtabs(-42) == 'xy' + def test_splitlines(self): s = "" assert s.splitlines() == [] diff --git a/pypy/objspace/std/test/test_intobject.py b/pypy/objspace/std/test/test_intobject.py --- a/pypy/objspace/std/test/test_intobject.py +++ b/pypy/objspace/std/test/test_intobject.py @@ -592,6 +592,12 @@ assert ns['a'] == 9007199254740991.0 assert ns['b'] == 9007199254740991.0 + def test_int_of_bool(self): + x = int(False) + assert x == 0 + assert type(x) is int + assert str(x) == "0" + class AppTestIntShortcut(AppTestInt): spaceconfig = {"objspace.std.intshortcut": True} diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py --- a/pypy/objspace/std/test/test_mapdict.py +++ b/pypy/objspace/std/test/test_mapdict.py @@ -451,12 +451,12 @@ obj = objectcls() obj.user_setup(space, cls) obj.setdictvalue(space, "a", w1) - assert unerase_item(obj._value0) is w1 + assert obj._value0 is w1 assert obj.getdictvalue(space, "a") is w1 assert obj.getdictvalue(space, "b") is None assert obj.getdictvalue(space, "c") is None obj.setdictvalue(space, "a", w2) - assert unerase_item(obj._value0) is w2 + assert obj._value0 is w2 assert obj.getdictvalue(space, "a") == w2 assert obj.getdictvalue(space, "b") is None assert obj.getdictvalue(space, "c") is None @@ -474,7 +474,7 @@ res = obj.deldictvalue(space, "a") assert res - assert unerase_item(obj._value0) is w4 + assert obj._value0 is w4 assert obj.getdictvalue(space, "a") is None assert obj.getdictvalue(space, "b") is w4 assert obj.getdictvalue(space, "c") is None diff --git a/pypy/objspace/std/test/test_unicodeobject.py b/pypy/objspace/std/test/test_unicodeobject.py --- a/pypy/objspace/std/test/test_unicodeobject.py +++ b/pypy/objspace/std/test/test_unicodeobject.py @@ -494,6 +494,10 @@ skip("Wrong platform") raises((OverflowError, MemoryError), u't\tt\t'.expandtabs, sys.maxint) + def test_expandtabs_0(self): + assert u'x\ty'.expandtabs(0) == u'xy' + assert u'x\ty'.expandtabs(-42) == u'xy' + def test_translate(self): assert u'bbbc' == u'abababc'.translate({ord('a'):None}) assert u'iiic' == u'abababc'.translate({ord('a'):None, ord('b'):ord('i')}) diff --git a/pypy/tool/pypyjit.py b/pypy/tool/pypyjit.py --- a/pypy/tool/pypyjit.py +++ b/pypy/tool/pypyjit.py @@ -14,6 +14,9 @@ print >> sys.stderr, __doc__ sys.exit(2) +import sys +sys.setrecursionlimit(100000000) + from pypy.objspace.std import Space from rpython.config.translationoption import set_opt_level from pypy.config.pypyoption import get_pypy_config, set_pypy_opt_level @@ -22,6 +25,7 @@ from rpython.rtyper.lltypesystem import lltype from pypy.interpreter.pycode import PyCode from rpython.translator.goal import unixcheckpoint +import pypy.module.pypyjit.interp_jit config = get_pypy_config(translating=True) config.translation.backendopt.inline_threshold = 0.1 @@ -33,6 +37,8 @@ config.objspace.usemodules.pypyjit = True config.objspace.usemodules.array = False config.objspace.usemodules._weakref = False +config.objspace.usemodules.struct = True +config.objspace.usemodules.time = True config.objspace.usemodules._sre = False config.objspace.usemodules._lsprof = False # @@ -73,6 +79,7 @@ read_code_ptr = llhelper(FPTR, read_code) def entry_point(): + space.startup() from pypy.module.marshal.interp_marshal import loads code = loads(space, space.wrap(hlstr(read_code_ptr()))) assert isinstance(code, PyCode) diff --git a/pypy/tool/pypyjit_demo.py b/pypy/tool/pypyjit_demo.py --- a/pypy/tool/pypyjit_demo.py +++ b/pypy/tool/pypyjit_demo.py @@ -1,8 +1,31 @@ -def f(): - i = 0 - while i < 1303: - i += 1 - return i +import time +l = [] -f() +for i in range(100): + print i + t0 = time.time() + exec """ +def k(a, b, c): + pass + +def g(a, b, c): + k(a, b + 1, c + 2) + k(a, b + 1, c + 2) + k(a, b + 1, c + 2) + k(a, b + 1, c + 2) + k(a, b + 1, c + 2) + +def f(i): + g(i, i + 1, i + 2) + g(i, i + 1, i + 2) + g(i, i + 1, i + 2) + g(i, i + 1, i + 2) + g(i, i + 1, i + 2) + g(i, i + 1, i + 2) +for i in range(1000): + f(i) +""" + l.append(time.time() - t0) + +print l diff --git a/pypy/tool/release/force-builds.py b/pypy/tool/release/force-builds.py --- a/pypy/tool/release/force-builds.py +++ b/pypy/tool/release/force-builds.py @@ -28,6 +28,7 @@ # 'pypy-c-app-level-win-x86-32', 'pypy-c-jit-linux-x86-32', 'pypy-c-jit-linux-x86-64', + 'pypy-c-jit-freebsd-9-x86-64', 'pypy-c-jit-macosx-x86-64', 'pypy-c-jit-win-x86-32', 'build-pypy-c-jit-linux-armhf-raring', @@ -42,7 +43,7 @@ import pwd return pwd.getpwuid(os.getuid())[0] -def main(branch, server): +def main(branch, server, user): #XXX: handle release tags #XXX: handle validity checks lock = defer.DeferredLock() @@ -56,7 +57,7 @@ print 'Forcing', builder, '...' url = "http://" + server + "/builders/" + builder + "/force" args = [ - ('username', get_user()), + ('username', user), ('revision', ''), ('forcescheduler', 'Force Scheduler'), ('submit', 'Force Build'), @@ -78,7 +79,8 @@ parser = optparse.OptionParser() parser.add_option("-b", "--branch", help="branch to build", default='') parser.add_option("-s", "--server", help="buildbot server", default="buildbot.pypy.org") + parser.add_option("-u", "--user", help="user name to report", default=get_user()) (options, args) = parser.parse_args() if not options.branch: parser.error("branch option required") - main(options.branch, options.server) + main(options.branch, options.server, user=options.user) diff --git a/pypy/tool/release/repackage.sh b/pypy/tool/release/repackage.sh --- a/pypy/tool/release/repackage.sh +++ b/pypy/tool/release/repackage.sh @@ -1,12 +1,12 @@ # Edit these appropriately before running this script maj=2 min=6 -rev=0 +rev=1 # This script will download latest builds from the buildmaster, rename the top # level directory, and repackage ready to be uploaded to bitbucket. It will also # download source, assuming a tag for the release already exists, and repackage them. -for plat in linux linux64 linux-armhf-raspbian linux-armhf-raring linux-armel osx64 +for plat in linux linux64 linux-armhf-raspbian linux-armhf-raring linux-armel osx64 freebsd64 do wget http://buildbot.pypy.org/nightly/release-$maj.$min.x/pypy-c-jit-latest-$plat.tar.bz2 tar -xf pypy-c-jit-latest-$plat.tar.bz2 diff --git a/rpython/annotator/binaryop.py b/rpython/annotator/binaryop.py --- a/rpython/annotator/binaryop.py +++ b/rpython/annotator/binaryop.py @@ -425,8 +425,9 @@ class __extend__(pairtype(SomeString, SomeObject), pairtype(SomeUnicodeString, SomeObject)): - def mod((s_string, args)): - return s_string.__class__() + def mod((s_string, s_arg)): + assert not isinstance(s_arg, SomeTuple) + return pair(s_string, SomeTuple([s_arg])).mod() class __extend__(pairtype(SomeFloat, SomeFloat)): diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py --- a/rpython/annotator/test/test_annrpython.py +++ b/rpython/annotator/test/test_annrpython.py @@ -2124,6 +2124,16 @@ assert isinstance(s, annmodel.SomeString) assert s.no_nul + def test_no_nul_mod(self): + def f(x): + s = "%d" % x + return s + a = self.RPythonAnnotator() + s = a.build_types(f, [int]) + assert isinstance(s, annmodel.SomeString) + assert s.no_nul + + def test_mul_str0(self): def f(s): return s*10 diff --git a/rpython/config/support.py b/rpython/config/support.py --- a/rpython/config/support.py +++ b/rpython/config/support.py @@ -8,7 +8,9 @@ if os.environ.get('MAKEFLAGS'): return 1 # don't override MAKEFLAGS. This will call 'make' without any '-j' option if sys.platform == 'darwin': - return darwin_get_cpu_count() + return sysctl_get_cpu_count('/usr/sbin/sysctl') + elif sys.platform.startswith('freebsd'): + return sysctl_get_cpu_count('/sbin/sysctl') elif not sys.platform.startswith('linux'): return 1 # implement me try: @@ -26,11 +28,10 @@ except: return 1 # we really don't want to explode here, at worst we have 1 -def darwin_get_cpu_count(cmd = "/usr/sbin/sysctl hw.ncpu"): +def sysctl_get_cpu_count(cmd, name='hw.ncpu'): try: - proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True) - # 'hw.ncpu: 20' - count = proc.communicate()[0].rstrip()[8:] + proc = subprocess.Popen([cmd, '-n', name], stdout=subprocess.PIPE) + count = proc.communicate()[0] return int(count) except (OSError, ValueError): return 1 diff --git a/rpython/config/test/test_support.py b/rpython/config/test/test_support.py --- a/rpython/config/test/test_support.py +++ b/rpython/config/test/test_support.py @@ -52,25 +52,30 @@ finally: os.environ = saved -def test_cpuinfo_darwin(): - if sys.platform != 'darwin': - py.test.skip('mac only') - saved_func = support.darwin_get_cpu_count +def test_cpuinfo_sysctl(): + if sys.platform != 'darwin' and not sys.platform.startswith('freebsd'): + py.test.skip('mac and bsd only') + saved_func = support.sysctl_get_cpu_count saved = os.environ - def count(): + def count(cmd): + if sys.platform == 'darwin': + assert cmd == '/usr/sbin/sysctl' + else: + assert cmd == '/sbin/sysctl' return 42 try: - support.darwin_get_cpu_count = count + support.sysctl_get_cpu_count = count os.environ = FakeEnviron(None) assert support.detect_number_of_processors() == 42 os.environ = FakeEnviron('-j2') assert support.detect_number_of_processors() == 1 finally: os.environ = saved - support.darwin_get_cpu_count = saved_func + support.sysctl_get_cpu_count = saved_func -def test_darwin_get_cpu_count(): - if sys.platform != 'darwin': - py.test.skip('mac only') - assert support.darwin_get_cpu_count() > 0 # hopefully - assert support.darwin_get_cpu_count("false") == 1 +def test_sysctl_get_cpu_count(): + if sys.platform != 'darwin' and not sys.platform.startswith('freebsd'): + py.test.skip('mac and bsd only') + cmd = '/usr/sbin/sysctl' if sys.platform != 'darwin' else '/sbin/sysctl' + assert support.sysctl_get_cpu_count(cmd) > 0 # hopefully + assert support.sysctl_get_cpu_count(cmd, "false") == 1 diff --git a/rpython/flowspace/objspace.py b/rpython/flowspace/objspace.py --- a/rpython/flowspace/objspace.py +++ b/rpython/flowspace/objspace.py @@ -13,6 +13,11 @@ def _assert_rpythonic(func): """Raise ValueError if ``func`` is obviously not RPython""" + try: + func.func_code.co_cellvars + except AttributeError: + raise ValueError("%r is not RPython: it is likely an unexpected " + "built-in function or type" % (func,)) if func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON'): raise ValueError("%r is tagged as NOT_RPYTHON" % (func,)) if func.func_code.co_cellvars: diff --git a/rpython/flowspace/test/test_objspace.py b/rpython/flowspace/test/test_objspace.py --- a/rpython/flowspace/test/test_objspace.py +++ b/rpython/flowspace/test/test_objspace.py @@ -1363,6 +1363,15 @@ simplify_graph(graph) assert self.all_operations(graph) == {'bool': 1, 'inplace_add': 1} + def test_unexpected_builtin_function(self): + import itertools + e = py.test.raises(ValueError, build_flow, itertools.permutations) + assert ' is not RPython:' in str(e.value) + e = py.test.raises(ValueError, build_flow, itertools.tee) + assert ' is not RPython:' in str(e.value) + e = py.test.raises(ValueError, build_flow, Exception.__init__) + assert ' is not RPython:' in str(e.value) + DATA = {'x': 5, 'y': 6} diff --git a/rpython/jit/backend/arm/runner.py b/rpython/jit/backend/arm/runner.py --- a/rpython/jit/backend/arm/runner.py +++ b/rpython/jit/backend/arm/runner.py @@ -64,12 +64,6 @@ operations, original_loop_token, log=log) - def clear_latest_values(self, count): - setitem = self.assembler.fail_boxes_ptr.setitem - null = lltype.nullptr(llmemory.GCREF.TO) - for index in range(count): - setitem(index, null) - def cast_ptr_to_int(x): adr = llmemory.cast_ptr_to_adr(x) return CPU_ARM.cast_adr_to_int(adr) 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 @@ -64,6 +64,7 @@ 'AMD64': MODEL_X86, # win64 'armv7l': MODEL_ARM, 'armv6l': MODEL_ARM, + 'arm': MODEL_ARM, # freebsd }.get(mach) if result is None: diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -153,15 +153,15 @@ rffi.cast(TYPE, -1) == -1) class ArrayDescr(AbstractDescr): - def __init__(self, A): + all_interiorfielddescrs = None + + def __init__(self, A, runner): self.A = self.OUTERA = A + self._is_pure = A._immutable_field(None) self.concrete_type = '\x00' if isinstance(A, lltype.Struct): self.A = A._flds[A._arrayfld] - def __repr__(self): - return 'ArrayDescr(%r)' % (self.OUTERA,) - def is_array_of_primitives(self): kind = getkind(self.A.OF) return kind == 'float' or \ @@ -169,13 +169,24 @@ kind == '' + def is_always_pure(self): + return self._is_pure + + def get_all_fielddescrs(self): + return self.all_interiorfielddescrs + + def __repr__(self): + return 'ArrayDescr(%r)' % (self.OUTERA,) + + def get_all_fielddescrs(self): + return self.all_interiorfielddescrs + + def __repr__(self): + return 'ArrayDescr(%r)' % (self.OUTERA,) + def is_array_of_pointers(self): return getkind(self.A.OF) == 'ref' - def getflag(self): - from rpython.jit.backend.llsupport.descr import get_type_flag - return get_type_flag(self.A.OF) - def is_array_of_floats(self): return getkind(self.A.OF) == 'float' @@ -206,12 +217,27 @@ return intbounds.get_integer_max( not _is_signed_kind(self.A.OF), rffi.sizeof(self.A.OF)) + def get_type_id(self): + assert isinstance(self.A, lltype.GcArray) + return TypeIDSymbolic(self.A) # integer-like symbolic + class InteriorFieldDescr(AbstractDescr): - def __init__(self, A, fieldname): + def __init__(self, A, fieldname, runner): self.A = A self.fieldname = fieldname self.FIELD = getattr(A.OF, fieldname) + self.arraydescr = runner.arraydescrof(A) + self.fielddescr = runner.fielddescrof(A.OF, fieldname) + + def get_index(self): + return self.fielddescr.get_index() + _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit