Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r65306:f4bbbcaa8ea3 Date: 2013-07-09 13:08 -0700 http://bitbucket.org/pypy/pypy/changeset/f4bbbcaa8ea3/
Log: merge default diff --git a/LICENSE b/LICENSE --- a/LICENSE +++ b/LICENSE @@ -2,9 +2,9 @@ ======= Except when otherwise stated (look for LICENSE files in directories or -information at the beginning of each file) all software and -documentation in the 'pypy', 'ctype_configure', 'dotviewer', 'demo', -and 'lib_pypy' directories is licensed as follows: +information at the beginning of each file) all software and documentation in +the 'rpython', 'pypy', 'ctype_configure', 'dotviewer', 'demo', and 'lib_pypy' +directories is licensed as follows: The MIT License diff --git a/pypy/doc/release-2.1.0-beta1.rst b/pypy/doc/release-2.1.0-beta1.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-2.1.0-beta1.rst @@ -0,0 +1,66 @@ +=============== +PyPy 2.1 beta 1 +=============== + +We're pleased to announce the first beta of the upcoming 2.1 release of PyPy. +This beta contains many bugfixes and improvements, numerous improvements to the +numpy in pypy effort. The main feature being that the ARM processor support is +not longer considered alpha level. We would like to thank the `Raspberry Pi +Foundation`_ for supporting the work to finish PyPy's ARM support. + +You can download the PyPy 2.1 beta 1 release here: + + http://pypy.org/download.html + +.. _`Raspberry Pi Foundation`: http://www.raspberrypi.org + +Highlights +========== + +* Bugfixes to the ARM JIT backend, so that ARM is now an officially + supported processor architecture. + +* Various numpy improvements. + +* Bugfixes to cffi and ctypes. + +* Bugfixes to the stacklet support + +* Improved logging performance + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7.3. It's fast due to its integrated tracing JIT compiler. + +This release supports x86 machines running Linux 32/64, Mac OS X 64 or Windows +32. Also this release supports ARM machines running Linux 32bit - anything with +``ARMv6`` (like the Raspberry Pi) or ``ARMv7`` (like Beagleboard, +Chromebook, Cubieboard, etc.) that supports ``VFPv3`` should work. Both +hard-float ``armhf/gnueabihf`` and soft-float ``armel/gnueabi`` builds are +provided. ``armhf`` builds for Raspbian are created using the Raspberry Pi +`custom cross-compilation toolchain <https://github.com/raspberrypi>`_ +based on ``gcc-arm-linux-gnueabihf`` and should work on ``ARMv6`` and +``ARMv7`` devices running Debian or Raspbian. ``armel`` builds are built +using the ``gcc-arm-linux-gnuebi`` toolchain provided by Ubuntu and +currently target ``ARMv7``. + +Windows 64 work is still stalling, we would welcome a volunteer +to handle that. + +How to use PyPy? +================ + +We suggest using PyPy from a `virtualenv`_. Once you have a virtualenv +installed, you can follow instructions from `pypy documentation`_ on how +to proceed. This document also covers other `installation schemes`_. + +.. _`pypy documentation`: http://doc.pypy.org/en/latest/getting-started.html#installing-using-virtualenv +.. _`virtualenv`: http://www.virtualenv.org/en/latest/ +.. _`installation schemes`: http://doc.pypy.org/en/latest/getting-started.html#installing-pypy +.. _`PyPy and pip`: http://doc.pypy.org/en/latest/getting-started.html#installing-pypy + + +Cheers, +the PyPy team diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py --- a/pypy/interpreter/gateway.py +++ b/pypy/interpreter/gateway.py @@ -359,7 +359,7 @@ (self.use(typ), self.nextarg())) def visit__ObjSpace(self, el): - if self.finger != 0: + if self.finger > 1: raise FastFuncNotSupported self.unwrap.append("space") @@ -432,21 +432,21 @@ mod = "" if mod == 'pypy.interpreter.astcompiler.ast': raise FastFuncNotSupported - if (not mod.startswith('pypy.module.__builtin__') and - not mod.startswith('pypy.module.sys') and - not mod.startswith('pypy.module.math')): - if not func.__name__.startswith('descr'): - raise FastFuncNotSupported + #if (not mod.startswith('pypy.module.__builtin__') and + # not mod.startswith('pypy.module.sys') and + # not mod.startswith('pypy.module.math')): + # if not func.__name__.startswith('descr'): + # raise FastFuncNotSupported d = {} unwrap_info.miniglobals['func'] = func source = """if 1: def fastfunc_%s_%d(%s): return func(%s) - \n""" % (func.__name__, narg, + \n""" % (func.__name__.replace('-', '_'), narg, ', '.join(args), ', '.join(unwrap_info.unwrap)) exec compile2(source) in unwrap_info.miniglobals, d - fastfunc = d['fastfunc_%s_%d' % (func.__name__, narg)] + fastfunc = d['fastfunc_%s_%d' % (func.__name__.replace('-', '_'), narg)] return narg, fastfunc make_fastfunc = staticmethod(make_fastfunc) diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py --- a/pypy/interpreter/test/test_gateway.py +++ b/pypy/interpreter/test/test_gateway.py @@ -609,6 +609,32 @@ assert space.is_true(w_res) assert called == [w_app_f, w_app_f] + def test_interp2app_fastcall_method_with_space(self): + class W_X(W_Root): + def descr_f(self, space, w_x): + return w_x + + app_f = gateway.interp2app_temp(W_X.descr_f, unwrap_spec=['self', + gateway.ObjSpace, gateway.W_Root]) + + w_app_f = self.space.wrap(app_f) + + assert isinstance(w_app_f.code, gateway.BuiltinCode2) + + called = [] + fastcall_2 = w_app_f.code.fastcall_2 + def witness_fastcall_2(space, w_func, w_a, w_b): + called.append(w_func) + return fastcall_2(space, w_func, w_a, w_b) + + w_app_f.code.fastcall_2 = witness_fastcall_2 + space = self.space + + w_res = space.call_function(w_app_f, W_X(), space.wrap(3)) + + assert space.is_true(w_res) + assert called == [w_app_f] + def test_plain(self): space = self.space 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 @@ -706,7 +706,7 @@ return MapDictIteratorValues(self.space, self, w_dict) def iteritems(self, w_dict): return MapDictIteratorItems(self.space, self, w_dict) - + def materialize_r_dict(space, obj, dict_w): map = obj._get_mapdict_map() @@ -714,69 +714,69 @@ _become(obj, new_obj) class MapDictIteratorKeys(BaseKeyIterator): - def __init__(self, space, strategy, dictimplementation): - BaseKeyIterator.__init__( - self, space, strategy, dictimplementation) - w_obj = strategy.unerase(dictimplementation.dstorage) - self.w_obj = w_obj - self.orig_map = self.curr_map = w_obj._get_mapdict_map() + def __init__(self, space, strategy, dictimplementation): + BaseKeyIterator.__init__(self, space, strategy, dictimplementation) + w_obj = strategy.unerase(dictimplementation.dstorage) + self.w_obj = w_obj + self.orig_map = self.curr_map = w_obj._get_mapdict_map() - def next_key_entry(self): - implementation = self.dictimplementation - assert isinstance(implementation.strategy, MapDictStrategy) - if self.orig_map is not self.w_obj._get_mapdict_map(): - return None - if self.curr_map: - curr_map = self.curr_map.search(DICT) - if curr_map: - self.curr_map = curr_map.back - attr = curr_map.selector[0] - w_attr = self.space.wrap(attr) - return w_attr - return None + def next_key_entry(self): + implementation = self.dictimplementation + assert isinstance(implementation.strategy, MapDictStrategy) + if self.orig_map is not self.w_obj._get_mapdict_map(): + return None + if self.curr_map: + curr_map = self.curr_map.search(DICT) + if curr_map: + self.curr_map = curr_map.back + attr = curr_map.selector[0] + w_attr = self.space.wrap(attr) + return w_attr + return None + class MapDictIteratorValues(BaseValueIterator): - def __init__(self, space, strategy, dictimplementation): - BaseValueIterator.__init__( - self, space, strategy, dictimplementation) - w_obj = strategy.unerase(dictimplementation.dstorage) - self.w_obj = w_obj - self.orig_map = self.curr_map = w_obj._get_mapdict_map() + def __init__(self, space, strategy, dictimplementation): + BaseValueIterator.__init__(self, space, strategy, dictimplementation) + w_obj = strategy.unerase(dictimplementation.dstorage) + self.w_obj = w_obj + self.orig_map = self.curr_map = w_obj._get_mapdict_map() - def next_value_entry(self): - implementation = self.dictimplementation - assert isinstance(implementation.strategy, MapDictStrategy) - if self.orig_map is not self.w_obj._get_mapdict_map(): - return None - if self.curr_map: - curr_map = self.curr_map.search(DICT) - if curr_map: - self.curr_map = curr_map.back - attr = curr_map.selector[0] - return self.w_obj.getdictvalue(self.space, attr) - return None + def next_value_entry(self): + implementation = self.dictimplementation + assert isinstance(implementation.strategy, MapDictStrategy) + if self.orig_map is not self.w_obj._get_mapdict_map(): + return None + if self.curr_map: + curr_map = self.curr_map.search(DICT) + if curr_map: + self.curr_map = curr_map.back + attr = curr_map.selector[0] + return self.w_obj.getdictvalue(self.space, attr) + return None + class MapDictIteratorItems(BaseItemIterator): - def __init__(self, space, strategy, dictimplementation): - BaseItemIterator.__init__( - self, space, strategy, dictimplementation) - w_obj = strategy.unerase(dictimplementation.dstorage) - self.w_obj = w_obj - self.orig_map = self.curr_map = w_obj._get_mapdict_map() + def __init__(self, space, strategy, dictimplementation): + BaseItemIterator.__init__(self, space, strategy, dictimplementation) + w_obj = strategy.unerase(dictimplementation.dstorage) + self.w_obj = w_obj + self.orig_map = self.curr_map = w_obj._get_mapdict_map() - def next_item_entry(self): - implementation = self.dictimplementation - assert isinstance(implementation.strategy, MapDictStrategy) - if self.orig_map is not self.w_obj._get_mapdict_map(): - return None, None - if self.curr_map: - curr_map = self.curr_map.search(DICT) - if curr_map: - self.curr_map = curr_map.back - attr = curr_map.selector[0] - w_attr = self.space.wrap(attr) - return w_attr, self.w_obj.getdictvalue(self.space, attr) - return None, None + def next_item_entry(self): + implementation = self.dictimplementation + assert isinstance(implementation.strategy, MapDictStrategy) + if self.orig_map is not self.w_obj._get_mapdict_map(): + return None, None + if self.curr_map: + curr_map = self.curr_map.search(DICT) + if curr_map: + self.curr_map = curr_map.back + attr = curr_map.selector[0] + w_attr = self.space.wrap(attr) + return w_attr, self.w_obj.getdictvalue(self.space, attr) + return None, None + # ____________________________________________________________ # Magic caching @@ -858,7 +858,7 @@ # selector = ("", INVALID) if w_descr is None: - selector = (name, DICT) #common case: no such attr in the class + selector = (name, DICT) # common case: no such attr in the class elif isinstance(w_descr, TypeCell): pass # we have a TypeCell in the class: give up elif space.is_data_descr(w_descr): @@ -888,7 +888,6 @@ LOAD_ATTR_slowpath._dont_inline_ = True def LOOKUP_METHOD_mapdict(f, nameindex, w_obj): - space = f.space pycode = f.getcode() entry = pycode._mapdict_caches[nameindex] if entry.is_valid_for_obj(w_obj): 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 @@ -740,6 +740,34 @@ s = a.build_types(f, [B]) assert s.classdef is a.bookkeeper.getuniqueclassdef(C) + def test_union_type_some_opbc(self): + class A(object): + name = "A" + + def f(self): + return type(self) + + class B(A): + name = "B" + + def f(tp): + return tp + + def main(n): + if n: + if n == 1: + inst = A() + else: + inst = B() + arg = inst.f() + else: + arg = B + return f(arg).name + + a = self.RPythonAnnotator() + s = a.build_types(main, [int]) + assert isinstance(s, annmodel.SomeString) + def test_ann_assert(self): def assert_(x): assert x,"XXX" diff --git a/rpython/jit/codewriter/effectinfo.py b/rpython/jit/codewriter/effectinfo.py --- a/rpython/jit/codewriter/effectinfo.py +++ b/rpython/jit/codewriter/effectinfo.py @@ -79,6 +79,9 @@ # OS_RAW_MALLOC_VARSIZE_CHAR = 110 OS_RAW_FREE = 111 + # + OS_STR_COPY_TO_RAW = 112 + OS_UNI_COPY_TO_RAW = 113 OS_JIT_FORCE_VIRTUAL = 120 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 @@ -1665,12 +1665,14 @@ dict = {"stroruni.concat": EffectInfo.OS_STR_CONCAT, "stroruni.slice": EffectInfo.OS_STR_SLICE, "stroruni.equal": EffectInfo.OS_STR_EQUAL, + "stroruni.copy_string_to_raw": EffectInfo.OS_STR_COPY_TO_RAW, } CHR = lltype.Char elif SoU.TO == rstr.UNICODE: dict = {"stroruni.concat": EffectInfo.OS_UNI_CONCAT, "stroruni.slice": EffectInfo.OS_UNI_SLICE, "stroruni.equal": EffectInfo.OS_UNI_EQUAL, + "stroruni.copy_string_to_raw": EffectInfo.OS_UNI_COPY_TO_RAW } CHR = lltype.UniChar else: diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py --- a/rpython/rtyper/lltypesystem/rffi.py +++ b/rpython/rtyper/lltypesystem/rffi.py @@ -677,7 +677,8 @@ def make_string_mappings(strtype): if strtype is str: - from rpython.rtyper.lltypesystem.rstr import STR as STRTYPE + from rpython.rtyper.lltypesystem.rstr import (STR as STRTYPE, + copy_string_to_raw) from rpython.rtyper.annlowlevel import llstr as llstrtype from rpython.rtyper.annlowlevel import hlstr as hlstrtype TYPEP = CCHARP @@ -685,7 +686,9 @@ lastchar = '\x00' builder_class = StringBuilder else: - from rpython.rtyper.lltypesystem.rstr import UNICODE as STRTYPE + from rpython.rtyper.lltypesystem.rstr import ( + UNICODE as STRTYPE, + copy_unicode_to_raw as copy_string_to_raw) from rpython.rtyper.annlowlevel import llunicode as llstrtype from rpython.rtyper.annlowlevel import hlunicode as hlstrtype TYPEP = CWCHARP @@ -702,11 +705,9 @@ else: array = lltype.malloc(TYPEP.TO, len(s) + 1, flavor='raw', track_allocation=False) i = len(s) + ll_s = llstrtype(s) + copy_string_to_raw(ll_s, array, 0, i) array[i] = lastchar - i -= 1 - while i >= 0: - array[i] = s[i] - i -= 1 return array str2charp._annenforceargs_ = [strtype, bool] @@ -739,14 +740,14 @@ string is already nonmovable. Must be followed by a free_nonmovingbuffer call. """ + lldata = llstrtype(data) if rgc.can_move(data): count = len(data) buf = lltype.malloc(TYPEP.TO, count, flavor='raw') - for i in range(count): - buf[i] = data[i] + copy_string_to_raw(lldata, buf, 0, count) return buf else: - data_start = cast_ptr_to_adr(llstrtype(data)) + \ + data_start = cast_ptr_to_adr(lldata) + \ offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0) return cast(TYPEP, data_start) get_nonmovingbuffer._annenforceargs_ = [strtype] diff --git a/rpython/rtyper/lltypesystem/rstr.py b/rpython/rtyper/lltypesystem/rstr.py --- a/rpython/rtyper/lltypesystem/rstr.py +++ b/rpython/rtyper/lltypesystem/rstr.py @@ -49,16 +49,18 @@ def emptyunicodefun(): return emptyunicode -def _new_copy_contents_fun(SRC_TP, DST_TP, CHAR_TP, name): - def _str_ofs_src(item): - return (llmemory.offsetof(SRC_TP, 'chars') + - llmemory.itemoffsetof(SRC_TP.chars, 0) + +def _new_copy_contents_fun(STR_TP, CHAR_TP, name): + def _str_ofs(item): + return (llmemory.offsetof(STR_TP, 'chars') + + llmemory.itemoffsetof(STR_TP.chars, 0) + llmemory.sizeof(CHAR_TP) * item) - def _str_ofs_dst(item): - return (llmemory.offsetof(DST_TP, 'chars') + - llmemory.itemoffsetof(DST_TP.chars, 0) + - llmemory.sizeof(CHAR_TP) * item) + @signature(types.any(), types.int(), returns=types.any()) + def _get_raw_buf(src, ofs): + assert typeOf(src).TO == STR_TP + assert ofs >= 0 + return llmemory.cast_ptr_to_adr(src) + _str_ofs(ofs) + _get_raw_buf._always_inline_ = True @jit.oopspec('stroruni.copy_contents(src, dst, srcstart, dststart, length)') @signature(types.any(), types.any(), types.int(), types.int(), types.int(), returns=types.none()) @@ -71,22 +73,42 @@ # because it might move the strings. The keepalive_until_here() # are obscurely essential to make sure that the strings stay alive # longer than the raw_memcopy(). - assert typeOf(src).TO == SRC_TP - assert typeOf(dst).TO == DST_TP - assert srcstart >= 0 - assert dststart >= 0 assert length >= 0 - src = llmemory.cast_ptr_to_adr(src) + _str_ofs_src(srcstart) - dst = llmemory.cast_ptr_to_adr(dst) + _str_ofs_dst(dststart) + # from here, no GC operations can happen + src = _get_raw_buf(src, srcstart) + dst = _get_raw_buf(dst, dststart) llmemory.raw_memcopy(src, dst, llmemory.sizeof(CHAR_TP) * length) + # end of "no GC" section keepalive_until_here(src) keepalive_until_here(dst) copy_string_contents._always_inline_ = True - return func_with_new_name(copy_string_contents, 'copy_%s_contents' % name) + copy_string_contents = func_with_new_name(copy_string_contents, + 'copy_%s_contents' % name) -copy_string_contents = _new_copy_contents_fun(STR, STR, Char, 'string') -copy_unicode_contents = _new_copy_contents_fun(UNICODE, UNICODE, UniChar, - 'unicode') + @jit.oopspec('stroruni.copy_string_to_raw(src, ptrdst, srcstart, length)') + def copy_string_to_raw(src, ptrdst, srcstart, length): + """ + Copies 'length' characters from the 'src' string to the 'ptrdst' + buffer, starting at position 'srcstart'. + 'ptrdst' must be a non-gc Array of Char. + """ + # xxx Warning: same note as above apply: don't do this at home + assert length >= 0 + # from here, no GC operations can happen + src = _get_raw_buf(src, srcstart) + adr = llmemory.cast_ptr_to_adr(ptrdst) + dstbuf = adr + llmemory.itemoffsetof(typeOf(ptrdst).TO, 0) + llmemory.raw_memcopy(src, dstbuf, llmemory.sizeof(CHAR_TP) * length) + # end of "no GC" section + keepalive_until_here(src) + copy_string_to_raw._always_inline_ = True + copy_string_to_raw = func_with_new_name(copy_string_to_raw, 'copy_%s_to_raw' % name) + + return copy_string_to_raw, copy_string_contents + +copy_string_to_raw, copy_string_contents = _new_copy_contents_fun(STR, Char, 'string') +copy_unicode_to_raw, copy_unicode_contents = _new_copy_contents_fun(UNICODE, + UniChar, 'unicode') CONST_STR_CACHE = WeakValueDictionary() CONST_UNICODE_CACHE = WeakValueDictionary() diff --git a/rpython/rtyper/test/test_rstr.py b/rpython/rtyper/test/test_rstr.py --- a/rpython/rtyper/test/test_rstr.py +++ b/rpython/rtyper/test/test_rstr.py @@ -1118,6 +1118,26 @@ res = self.interpret(f, [5]) assert res == 0 + def test_copy_string_to_raw(self): + from rpython.rtyper.lltypesystem import lltype, llmemory + from rpython.rtyper.annlowlevel import llstr + from rpython.rtyper.lltypesystem.rstr import copy_string_to_raw + + def f(buf, n): + s = 'abc' * n + ll_s = llstr(s) + copy_string_to_raw(ll_s, buf, 0, n*3) + + TP = lltype.Array(lltype.Char) + array = lltype.malloc(TP, 12, flavor='raw') + f(array, 4) + assert list(array) == list('abc'*4) + lltype.free(array, flavor='raw') + + array = lltype.malloc(TP, 12, flavor='raw') + self.interpret(f, [array, 4]) + assert list(array) == list('abc'*4) + lltype.free(array, flavor='raw') class TestOOtype(BaseTestRstr, OORtypeMixin): pass _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit