Author: Philip Jenvey <pjen...@underboss.org> Branch: py3k Changeset: r65911:de2ab686aa9d Date: 2013-08-02 12:03 -0700 http://bitbucket.org/pypy/pypy/changeset/de2ab686aa9d/
Log: merge default diff --git a/lib_pypy/_curses.py b/lib_pypy/_curses.py --- a/lib_pypy/_curses.py +++ b/lib_pypy/_curses.py @@ -966,7 +966,7 @@ r, g, b = ffi.new("short *"), ffi.new("short *"), ffi.new("short *") if lib.color_content(color, r, g, b) == lib.ERR: raise error("Argument 1 was out of range. Check value of COLORS.") - return (r, g, b) + return (r[0], g[0], b[0]) def color_pair(n): @@ -1121,6 +1121,7 @@ term = ffi.NULL err = ffi.new("int *") if lib.setupterm(term, fd, err) == lib.ERR: + err = err[0] if err == 0: raise error("setupterm: could not find terminal") elif err == -1: diff --git a/lib_pypy/_sqlite3.py b/lib_pypy/_sqlite3.py --- a/lib_pypy/_sqlite3.py +++ b/lib_pypy/_sqlite3.py @@ -1317,7 +1317,7 @@ for i in xrange(_lib.sqlite3_column_count(self._statement)): name = _lib.sqlite3_column_name(self._statement, i) if name: - name = _ffi.string(name).decode('utf-8').split("[")[0].strip() + name = _ffi.string(name).split("[")[0].strip() desc.append((name, None, None, None, None, None, None)) return desc diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py --- a/pypy/doc/conf.py +++ b/pypy/doc/conf.py @@ -45,9 +45,9 @@ # built documents. # # The short X.Y version. -version = '2.0' +version = '2.1' # The full version, including alpha/beta/rc tags. -release = '2.0.2' +release = '2.1.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/pypy/doc/getting-started-python.rst b/pypy/doc/getting-started-python.rst --- a/pypy/doc/getting-started-python.rst +++ b/pypy/doc/getting-started-python.rst @@ -104,8 +104,8 @@ executable. The executable behaves mostly like a normal Python interpreter:: $ ./pypy-c - Python 2.7.3 (7e4f0faa3d51, Nov 22 2012, 10:35:18) - [PyPy 2.0.0 with GCC 4.7.1] on linux2 + Python 2.7.3 (480845e6b1dd, Jul 31 2013, 11:05:31) + [PyPy 2.1.0 with GCC 4.7.1] on linux2 Type "help", "copyright", "credits" or "license" for more information. And now for something completely different: ``RPython magically makes you rich and famous (says so on the tin)'' @@ -171,7 +171,7 @@ the ``bin/pypy`` executable. To install PyPy system wide on unix-like systems, it is recommended to put the -whole hierarchy alone (e.g. in ``/opt/pypy2.0``) and put a symlink to the +whole hierarchy alone (e.g. in ``/opt/pypy2.1``) and put a symlink to the ``pypy`` executable into ``/usr/bin`` or ``/usr/local/bin`` If the executable fails to find suitable libraries, it will report diff --git a/pypy/doc/getting-started.rst b/pypy/doc/getting-started.rst --- a/pypy/doc/getting-started.rst +++ b/pypy/doc/getting-started.rst @@ -53,10 +53,10 @@ PyPy is ready to be executed as soon as you unpack the tarball or the zip file, with no need to install it in any specific location:: - $ tar xf pypy-2.0.tar.bz2 - $ ./pypy-2.0/bin/pypy - Python 2.7.3 (7e4f0faa3d51, Nov 22 2012, 10:35:18) - [PyPy 2.0.0 with GCC 4.7.1] on linux2 + $ tar xf pypy-2.1.tar.bz2 + $ ./pypy-2.1/bin/pypy + Python 2.7.3 (480845e6b1dd, Jul 31 2013, 11:05:31) + [PyPy 2.1.0 with GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. And now for something completely different: ``PyPy is an exciting technology that lets you to write fast, portable, multi-platform interpreters with less @@ -75,14 +75,14 @@ $ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py - $ ./pypy-2.0/bin/pypy distribute_setup.py + $ ./pypy-2.1/bin/pypy distribute_setup.py - $ ./pypy-2.0/bin/pypy get-pip.py + $ ./pypy-2.1/bin/pypy get-pip.py - $ ./pypy-2.0/bin/pip install pygments # for example + $ ./pypy-2.1/bin/pip install pygments # for example -3rd party libraries will be installed in ``pypy-2.0/site-packages``, and -the scripts in ``pypy-2.0/bin``. +3rd party libraries will be installed in ``pypy-2.1/site-packages``, and +the scripts in ``pypy-2.1/bin``. Installing using virtualenv --------------------------- diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst --- a/pypy/doc/index.rst +++ b/pypy/doc/index.rst @@ -40,7 +40,7 @@ * `FAQ`_: some frequently asked questions. -* `Release 2.0.2`_: the latest official release +* `Release 2.1.0`_: the latest official release * `PyPy Blog`_: news and status info about PyPy @@ -110,7 +110,7 @@ .. _`Getting Started`: getting-started.html .. _`Papers`: extradoc.html .. _`Videos`: video-index.html -.. _`Release 2.0.2`: http://pypy.org/download.html +.. _`Release 2.1.0`: http://pypy.org/download.html .. _`speed.pypy.org`: http://speed.pypy.org .. _`RPython toolchain`: translation.html .. _`potential project ideas`: project-ideas.html diff --git a/pypy/doc/release-2.1.0.rst b/pypy/doc/release-2.1.0.rst new file mode 100644 --- /dev/null +++ b/pypy/doc/release-2.1.0.rst @@ -0,0 +1,89 @@ +============================ +PyPy 2.1 - Considered ARMful +============================ + +We're pleased to announce PyPy 2.1, which targets version 2.7.3 of the Python +language. This is the first release with official support for ARM processors in the JIT. +This release also contains several bugfixes and performance improvements. + +You can download the PyPy 2.1 release here: + + http://pypy.org/download.html + +We would like to thank the `Raspberry Pi Foundation`_ for supporting the work +to finish PyPy's ARM support. + +.. _`Raspberry Pi Foundation`: http://www.raspberrypi.org + +The first beta of PyPy3 2.1, targeting version 3 of the Python language, was +just released, more details can be found `here`_. + +.. _`here`: http://morepypy.blogspot.com/2013/07/pypy3-21-beta-1.html + +What is PyPy? +============= + +PyPy is a very compliant Python interpreter, almost a drop-in replacement for +CPython 2.7. It's fast (`pypy 2.1 and cpython 2.7.2`_ performance comparison) +due to its integrated tracing JIT compiler. + +This release supports x86 machines running Linux 32/64, Mac OS X 64 or Windows +32. This release also supports ARM machines running Linux 32bit - anything with +``ARMv6`` (like the Raspberry Pi) or ``ARMv7`` (like the 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. + +.. _`pypy 2.1 and cpython 2.7.2`: http://speed.pypy.org + +Highlights +========== + +* JIT support for ARM, architecture versions 6 and 7, hard- and soft-float ABI + +* Stacklet support for ARM + +* Support for os.statvfs and os.fstatvfs on unix systems + +* Improved logging performance + +* Faster sets for objects + +* Interpreter improvements + +* During packaging, compile the CFFI based TK extension + +* Pickling of numpy arrays and dtypes + +* Subarrays for numpy + +* Bugfixes to numpy + +* Bugfixes to cffi and ctypes + +* Bugfixes to the x86 stacklet support + +* Fixed issue `1533`_: fix an RPython-level OverflowError for space.float_w(w_big_long_number). + +* Fixed issue `1552`_: GreenletExit should inherit from BaseException. + +* Fixed issue `1537`_: numpypy __array_interface__ + +* Fixed issue `1238`_: Writing to an SSL socket in PyPy sometimes failed with a "bad write retry" message. + +.. _`1533`: https://bugs.pypy.org/issue1533 +.. _`1552`: https://bugs.pypy.org/issue1552 +.. _`1537`: https://bugs.pypy.org/issue1537 +.. _`1238`: https://bugs.pypy.org/issue1238 + +Cheers, + +David Schneider for the PyPy team. 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 @@ -52,3 +52,13 @@ .. branch: fast-slowpath Added an abstraction for functions with a fast and slow path in the JIT. This speeds up list.append() and list.pop(). + +.. branch: curses_fixes + +.. branch: foldable-getarrayitem-indexerror +Constant-fold reading out of constant tuples in PyPy. + +.. branch: mro-reorder-numpypy-str +No longer delegate numpy string_ methods to space.StringObject, in numpy +this works by kind of by accident. Support for merging the refactor-str-types +branch diff --git a/pypy/module/cpyext/include/patchlevel.h b/pypy/module/cpyext/include/patchlevel.h --- a/pypy/module/cpyext/include/patchlevel.h +++ b/pypy/module/cpyext/include/patchlevel.h @@ -29,7 +29,7 @@ #define PY_VERSION "3.2.3" /* PyPy version as a string */ -#define PYPY_VERSION "2.1.0-alpha0" +#define PYPY_VERSION "2.2.0-alpha0" /* Subversion Revision number of this file (not of the repository). * Empty since Mercurial migration. */ 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 @@ -852,15 +852,10 @@ # Depending on which opcodes are enabled, eg. CALL_METHOD we bump the version # number by some constant # -# * CALL_METHOD +2 -# -# In other words: -# -# default_magic -- used by CPython without the -U option -# default_magic + 1 -- used by CPython with the -U option -# default_magic + 2 -- used by PyPy without any extra opcode -# ... -# default_magic + 5 -- used by PyPy with both extra opcodes +# default_magic - 6 -- used by CPython without the -U option +# default_magic - 5 -- used by CPython with the -U option +# default_magic -- used by PyPy without the CALL_METHOD opcode +# default_magic + 2 -- used by PyPy with the CALL_METHOD opcode # from pypy.interpreter.pycode import default_magic MARSHAL_VERSION_FOR_PYC = 2 diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py --- a/pypy/module/micronumpy/base.py +++ b/pypy/module/micronumpy/base.py @@ -37,7 +37,8 @@ from pypy.module.micronumpy.arrayimpl import concrete, scalar if not shape: - impl = scalar.Scalar(dtype.base) + w_val = dtype.base.coerce(space, space.wrap(0)) + impl = scalar.Scalar(dtype.base, w_val) else: strides, backstrides = calc_strides(shape, dtype.base, order) impl = concrete.ConcreteArray(shape, dtype.base, order, strides, @@ -79,6 +80,8 @@ if w_val is not None: w_val = dtype.coerce(space, w_val) + else: + w_val = dtype.coerce(space, space.wrap(0)) return W_NDimArray(scalar.Scalar(dtype, w_val)) diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py --- a/pypy/module/micronumpy/interp_boxes.py +++ b/pypy/module/micronumpy/interp_boxes.py @@ -205,6 +205,7 @@ descr_neg = _unaryop_impl("negative") descr_abs = _unaryop_impl("absolute") descr_invert = _unaryop_impl("invert") + descr_conjugate = _unaryop_impl("conjugate") def descr_divmod(self, space, w_other): w_quotient = self.descr_div(space, w_other) @@ -378,12 +379,14 @@ return self class W_CharacterBox(W_FlexibleBox): - pass + def convert_to(self, dtype): + # XXX assert dtype is str type + return self + class W_StringBox(W_CharacterBox): def descr__new__string_box(space, w_subtype, w_arg): from pypy.module.micronumpy.interp_dtype import new_string_dtype - arg = space.str_w(space.str(w_arg)) arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): @@ -517,6 +520,7 @@ all = interp2app(W_GenericBox.descr_all), ravel = interp2app(W_GenericBox.descr_ravel), round = interp2app(W_GenericBox.descr_round), + conjugate = interp2app(W_GenericBox.descr_conjugate), view = interp2app(W_GenericBox.descr_view), ) @@ -682,12 +686,12 @@ __module__ = "numpypy", ) -W_StringBox.typedef = TypeDef("string_", (str_typedef, W_CharacterBox.typedef), +W_StringBox.typedef = TypeDef("string_", (W_CharacterBox.typedef, str_typedef), __module__ = "numpypy", __new__ = interp2app(W_StringBox.descr__new__string_box.im_func), ) -W_UnicodeBox.typedef = TypeDef("unicode_", (unicode_typedef, W_CharacterBox.typedef), +W_UnicodeBox.typedef = TypeDef("unicode_", (W_CharacterBox.typedef, unicode_typedef), __module__ = "numpypy", __new__ = interp2app(W_UnicodeBox.descr__new__unicode_box.im_func), ) diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py --- a/pypy/module/micronumpy/interp_dtype.py +++ b/pypy/module/micronumpy/interp_dtype.py @@ -234,6 +234,9 @@ def is_record_type(self): return self.fields is not None + def is_str_type(self): + return self.num == 18 + def is_str_or_unicode(self): return (self.num == 18 or self.num == 19) diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py --- a/pypy/module/micronumpy/interp_ufuncs.py +++ b/pypy/module/micronumpy/interp_ufuncs.py @@ -328,14 +328,19 @@ w_out = None w_lhs = convert_to_array(space, w_lhs) w_rhs = convert_to_array(space, w_rhs) - if (w_lhs.get_dtype().is_flexible_type() or \ - w_rhs.get_dtype().is_flexible_type()): + w_ldtype = w_lhs.get_dtype() + w_rdtype = w_rhs.get_dtype() + if w_ldtype.is_str_type() and w_rdtype.is_str_type() and \ + self.comparison_func: + pass + elif (w_ldtype.is_flexible_type() or \ + w_rdtype.is_flexible_type()): raise OperationError(space.w_TypeError, space.wrap( 'unsupported operand dtypes %s and %s for "%s"' % \ - (w_rhs.get_dtype().get_name(), w_lhs.get_dtype().get_name(), + (w_rdtype.get_name(), w_ldtype.get_name(), self.name))) calc_dtype = find_binop_result_dtype(space, - w_lhs.get_dtype(), w_rhs.get_dtype(), + w_ldtype, w_rdtype, int_only=self.int_only, promote_to_float=self.promote_to_float, promote_bools=self.promote_bools, diff --git a/pypy/module/micronumpy/stdobjspace.py b/pypy/module/micronumpy/stdobjspace.py deleted file mode 100644 --- a/pypy/module/micronumpy/stdobjspace.py +++ /dev/null @@ -1,11 +0,0 @@ - -from pypy.objspace.std import stringobject -from pypy.module.micronumpy import interp_boxes - -def delegate_stringbox2stringobj(space, w_box): - return space.wrap(w_box.dtype.itemtype.to_str(w_box)) - -def register_delegates(typeorder): - typeorder[interp_boxes.W_StringBox] = [ - (stringobject.W_StringObject, delegate_stringbox2stringobj), - ] diff --git a/pypy/module/micronumpy/test/test_complex.py b/pypy/module/micronumpy/test/test_complex.py --- a/pypy/module/micronumpy/test/test_complex.py +++ b/pypy/module/micronumpy/test/test_complex.py @@ -400,6 +400,7 @@ assert conj is conjugate assert conj(c0) == c0 + assert c0.conjugate() == c0 assert conj(c1) == complex(1, -2) assert conj(1) == 1 assert conj(-3) == -3 @@ -625,6 +626,8 @@ a = array([1 + 2j, 1 - 2j]) assert (a.conj() == [1 - 2j, 1 + 2j]).all() + a = array([1,2,3.4J],dtype=complex) + assert a[2].conjugate() == 0-3.4j def test_math(self): if self.isWindows: 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 @@ -739,6 +739,7 @@ class AppTestStrUnicodeDtypes(BaseNumpyAppTest): def test_str_unicode(self): + skip('numpypy differs from numpy') from numpypy import str_, unicode_, character, flexible, generic assert str_.mro() == [str_, str, character, flexible, generic, object] diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py --- a/pypy/module/micronumpy/test/test_numarray.py +++ b/pypy/module/micronumpy/test/test_numarray.py @@ -264,6 +264,8 @@ assert a.dtype is dtype(int) a = ndarray([], dtype=float) assert a.shape == () + # test uninitialized value crash? + assert len(str(a)) > 0 def test_ndmin(self): from numpypy import array @@ -2754,6 +2756,19 @@ assert a[2] == 'ab' raises(TypeError, a, 'sum') raises(TypeError, 'a+a') + b = array(['abcdefg', 'ab', 'cd']) + assert a[2] == b[1] + assert bool(a[1]) + c = array(['ab','cdefg','hi','jk']) + # not implemented yet + #c[0] += c[3] + #assert c[0] == 'abjk' + + def test_to_str(self): + from numpypy import array + a = array(['abc','abc', 'def', 'ab'], 'S3') + b = array(['mnopqr','abcdef', 'ab', 'cd']) + assert b[1] != a[1] def test_string_scalar(self): from numpypy import array @@ -2765,8 +2780,7 @@ assert str(a.dtype) == '|S1' a = array('x', dtype='c') assert str(a.dtype) == '|S1' - # XXX can sort flexible types, why not comparison? - #assert a == 'x' + assert a == 'x' def test_flexible_repr(self): from numpypy import array diff --git a/pypy/module/micronumpy/tool/numready/main.py b/pypy/module/micronumpy/tool/numready/main.py --- a/pypy/module/micronumpy/tool/numready/main.py +++ b/pypy/module/micronumpy/tool/numready/main.py @@ -78,6 +78,11 @@ items.add(Item(name, kind, subitems)) return items +def get_version_str(python): + args = [python, '-c', 'import sys; print sys.version'] + lines = subprocess.check_output(args).splitlines() + return lines[0] + def split(lst): SPLIT = 5 lgt = len(lst) // SPLIT + 1 @@ -93,6 +98,7 @@ def main(argv): cpy_items = find_numpy_items("/usr/bin/python") pypy_items = find_numpy_items(argv[1], "numpypy") + ver = get_version_str(argv[1]) all_items = [] msg = "{:d}/{:d} names".format(len(pypy_items), len(cpy_items)) + " " @@ -113,7 +119,8 @@ env = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname(__file__)) ) - html = env.get_template("page.html").render(all_items=split(sorted(all_items)), msg=msg) + html = env.get_template("page.html").render(all_items=split(sorted(all_items)), + msg=msg, ver=ver) if len(argv) > 2: with open(argv[2], 'w') as f: f.write(html.encode("utf-8")) diff --git a/pypy/module/micronumpy/tool/numready/page.html b/pypy/module/micronumpy/tool/numready/page.html --- a/pypy/module/micronumpy/tool/numready/page.html +++ b/pypy/module/micronumpy/tool/numready/page.html @@ -34,6 +34,7 @@ </head> <body> <h1>NumPyPy Status</h1> + <h3>Version: {{ ver }}</h3> <h3>Overall: {{ msg }}</h3> <table> <thead> diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py --- a/pypy/module/micronumpy/types.py +++ b/pypy/module/micronumpy/types.py @@ -1689,6 +1689,22 @@ def get_size(self): return self.size +def str_unary_op(func): + specialize.argtype(1)(func) + @functools.wraps(func) + def dispatcher(self, v1): + return func(self, self.to_str(v1)) + return dispatcher + +def str_binary_op(func): + specialize.argtype(1, 2)(func) + @functools.wraps(func) + def dispatcher(self, v1, v2): + return func(self, + self.to_str(v1), + self.to_str(v2) + ) + return dispatcher class StringType(BaseType, BaseStringType): T = lltype.Char @@ -1696,6 +1712,8 @@ @jit.unroll_safe def coerce(self, space, dtype, w_item): from pypy.module.micronumpy.interp_dtype import new_string_dtype + if isinstance(w_item, interp_boxes.W_StringBox): + return w_item arg = space.str_w(space.str(w_item)) arr = VoidBoxStorage(len(arg), new_string_dtype(space, len(arg))) for i in range(len(arg)): @@ -1705,6 +1723,7 @@ @jit.unroll_safe def store(self, arr, i, offset, box): assert isinstance(box, interp_boxes.W_StringBox) + # XXX simplify to range(box.dtype.get_size()) ? for k in range(min(self.size, box.arr.size-offset)): arr.storage[k + i] = box.arr.storage[k + offset] @@ -1718,7 +1737,7 @@ builder = StringBuilder() assert isinstance(item, interp_boxes.W_StringBox) i = item.ofs - end = i+self.size + end = i + item.dtype.get_size() while i < end: assert isinstance(item.arr.storage[i], str) if item.arr.storage[i] == '\x00': @@ -1734,10 +1753,53 @@ builder.append("'") return builder.build() - # XXX move to base class when UnicodeType is supported + # XXX move the rest of this to base class when UnicodeType is supported def to_builtin_type(self, space, box): return space.wrap(self.to_str(box)) + @str_binary_op + def eq(self, v1, v2): + return v1 == v2 + + @str_binary_op + def ne(self, v1, v2): + return v1 != v2 + + @str_binary_op + def lt(self, v1, v2): + return v1 < v2 + + @str_binary_op + def le(self, v1, v2): + return v1 <= v2 + + @str_binary_op + def gt(self, v1, v2): + return v1 > v2 + + @str_binary_op + def ge(self, v1, v2): + return v1 >= v2 + + @str_binary_op + def logical_and(self, v1, v2): + return bool(v1) and bool(v2) + + @str_binary_op + def logical_or(self, v1, v2): + return bool(v1) or bool(v2) + + @str_unary_op + def logical_not(self, v): + return not bool(v) + + @str_binary_op + def logical_xor(self, v1, v2): + return bool(v1) ^ bool(v2) + + def bool(self, v): + return bool(self.to_str(v)) + def build_and_convert(self, space, mydtype, box): assert isinstance(box, interp_boxes.W_GenericBox) if box.get_dtype(space).is_str_or_unicode(): @@ -1753,6 +1815,13 @@ arr.storage[j] = '\x00' return interp_boxes.W_StringBox(arr, 0, arr.dtype) +NonNativeStringType = StringType + +class UnicodeType(BaseType, BaseStringType): + T = lltype.UniChar + +NonNativeUnicodeType = UnicodeType + class VoidType(BaseType, BaseStringType): T = lltype.Char @@ -1798,12 +1867,6 @@ return W_NDimArray(implementation) NonNativeVoidType = VoidType -NonNativeStringType = StringType - -class UnicodeType(BaseType, BaseStringType): - T = lltype.UniChar - -NonNativeUnicodeType = UnicodeType class RecordType(BaseType): diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py --- a/pypy/module/pypyjit/test_pypy_c/test_containers.py +++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py @@ -209,6 +209,22 @@ opnames = log.opnames(loop.allops()) assert opnames.count('new_with_vtable') == 0 + def test_constfold_tuple(self): + code = """if 1: + tup = tuple(range(10000)) + l = [1, 2, 3, 4, 5, 6, "a"] + def main(n): + while n > 0: + sub = tup[1] # ID: getitem + l[1] = n # kill cache of tup[1] + n -= sub + """ + log = self.run(code, [1000]) + loop, = log.loops_by_filename(self.filepath) + ops = loop.ops_by_id('getitem', include_guard_not_invalidated=False) + assert log.opnames(ops) == [] + + def test_specialised_tuple(self): def main(n): import pypyjit diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py --- a/pypy/module/sys/version.py +++ b/pypy/module/sys/version.py @@ -11,7 +11,7 @@ #XXX # sync CPYTHON_VERSION with patchlevel.h, package.py CPYTHON_API_VERSION = 1013 #XXX # sync with include/modsupport.h -PYPY_VERSION = (2, 1, 0, "alpha", 0) #XXX # sync patchlevel.h +PYPY_VERSION = (2, 2, 0, "alpha", 0) #XXX # sync patchlevel.h if platform.name == 'msvc': COMPILER_INFO = 'MSC v.%d 32 bit' % (platform.version * 10 + 600) diff --git a/pypy/module/test_lib_pypy/test_curses.py b/pypy/module/test_lib_pypy/test_curses.py new file mode 100644 --- /dev/null +++ b/pypy/module/test_lib_pypy/test_curses.py @@ -0,0 +1,48 @@ +from lib_pypy import _curses + +import pytest + +lib = _curses.lib + + +def test_color_content(monkeypatch): + def lib_color_content(color, r, g, b): + r[0], g[0], b[0] = 42, 43, 44 + return lib.OK + + monkeypatch.setattr(_curses, '_ensure_initialised_color', lambda: None) + monkeypatch.setattr(lib, 'color_content', lib_color_content) + + assert _curses.color_content(None) == (42, 43, 44) + + +def test_setupterm(monkeypatch): + def make_setupterm(err_no): + def lib_setupterm(term, fd, err): + err[0] = err_no + + return lib.ERR + + return lib_setupterm + + monkeypatch.setattr(_curses, '_initialised_setupterm', False) + monkeypatch.setattr(lib, 'setupterm', make_setupterm(0)) + + with pytest.raises(Exception) as exc_info: + _curses.setupterm() + + assert "could not find terminal" in exc_info.value.args[0] + + monkeypatch.setattr(lib, 'setupterm', make_setupterm(-1)) + + with pytest.raises(Exception) as exc_info: + _curses.setupterm() + + assert "could not find terminfo database" in exc_info.value.args[0] + + monkeypatch.setattr(lib, 'setupterm', make_setupterm(42)) + + with pytest.raises(Exception) as exc_info: + _curses.setupterm() + + assert "unknown error" in exc_info.value.args[0] diff --git a/pypy/module/test_lib_pypy/test_sqlite3.py b/pypy/module/test_lib_pypy/test_sqlite3.py --- a/pypy/module/test_lib_pypy/test_sqlite3.py +++ b/pypy/module/test_lib_pypy/test_sqlite3.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- """Tests for _sqlite3.py""" import pytest, sys @@ -222,3 +223,8 @@ cur.execute("create table test(a)") cur.executemany("insert into test values (?)", [[1], [2], [3]]) assert cur.lastrowid is None + +def test_issue1573(con): + cur = con.cursor() + cur.execute(u'SELECT 1 as méil') + assert cur.description[0][0] == u"méil".encode('utf-8') diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py --- a/pypy/objspace/std/listobject.py +++ b/pypy/objspace/std/listobject.py @@ -678,11 +678,13 @@ find_jmp = jit.JitDriver(greens = [], reds = 'auto', name = 'list.find') class ListStrategy(object): - sizehint = -1 def __init__(self, space): self.space = space + def get_sizehint(self): + return -1 + def init_from_list_w(self, w_list, list_w): raise NotImplementedError @@ -870,7 +872,7 @@ else: strategy = self.space.fromcache(ObjectListStrategy) - storage = strategy.get_empty_storage(self.sizehint) + storage = strategy.get_empty_storage(self.get_sizehint()) w_list.strategy = strategy w_list.lstorage = storage @@ -953,6 +955,9 @@ self.sizehint = sizehint ListStrategy.__init__(self, space) + def get_sizehint(self): + return self.sizehint + def _resize_hint(self, w_list, hint): assert hint >= 0 self.sizehint = hint diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py --- a/pypy/objspace/std/model.py +++ b/pypy/objspace/std/model.py @@ -132,10 +132,6 @@ # when trying to dispatch multimethods. # XXX build these lists a bit more automatically later - if config.objspace.usemodules.micronumpy: - from pypy.module.micronumpy.stdobjspace import register_delegates - register_delegates(self.typeorder) - self.typeorder[boolobject.W_BoolObject] += [ #(intobject.W_IntObject, boolobject.delegate_Bool2IntObject), (floatobject.W_FloatObject, floatobject.delegate_Bool2Float), 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 @@ -19,6 +19,7 @@ BUILDERS = [ 'own-linux-x86-32', 'own-linux-x86-64', + 'own-linux-armhf', # 'own-macosx-x86-32', # 'pypy-c-app-level-linux-x86-32', # 'pypy-c-app-level-linux-x86-64', diff --git a/rpython/jit/backend/llsupport/test/test_gc_integration.py b/rpython/jit/backend/llsupport/test/test_gc_integration.py --- a/rpython/jit/backend/llsupport/test/test_gc_integration.py +++ b/rpython/jit/backend/llsupport/test/test_gc_integration.py @@ -88,7 +88,7 @@ else: assert nos == [0, 1, 25] elif self.cpu.backend_name.startswith('arm'): - assert nos == [9, 10, 47] + assert nos == [0, 1, 47] else: raise Exception("write the data here") assert frame.jf_frame[nos[0]] diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py --- a/rpython/jit/backend/model.py +++ b/rpython/jit/backend/model.py @@ -187,10 +187,6 @@ # with Voids removed raise NotImplementedError - def methdescrof(self, SELFTYPE, methname): - # must return a subclass of history.AbstractMethDescr - raise NotImplementedError - def typedescrof(self, TYPE): raise NotImplementedError diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -799,6 +799,15 @@ consider_cond_call_gc_wb_array = consider_cond_call_gc_wb def consider_cond_call(self, op): + # A 32-bit-only, asmgcc-only issue: 'cond_call_register_arguments' + # contains edi and esi, which are also in asmgcroot.py:ASM_FRAMEDATA. + # We must make sure that edi and esi do not contain GC pointers. + if IS_X86_32 and self.assembler._is_asmgcc(): + for box, loc in self.rm.reg_bindings.items(): + if (loc == edi or loc == esi) and box.type == REF: + self.rm.force_spill_var(box) + assert box not in self.rm.reg_bindings + # assert op.result is None args = op.getarglist() assert 2 <= len(args) <= 4 + 2 # maximum 4 arguments diff --git a/rpython/jit/metainterp/history.py b/rpython/jit/metainterp/history.py --- a/rpython/jit/metainterp/history.py +++ b/rpython/jit/metainterp/history.py @@ -34,7 +34,6 @@ return 'int' # singlefloats are stored in an int if TYPE in (lltype.Float, lltype.SingleFloat): raise NotImplementedError("type %s not supported" % TYPE) - # XXX fix this for oo... if (TYPE != llmemory.Address and rffi.sizeof(TYPE) > rffi.sizeof(lltype.Signed)): if supports_longlong and TYPE is not lltype.LongFloat: @@ -168,18 +167,11 @@ def __init__(self, identifier=None): self.identifier = identifier # for testing + class BasicFailDescr(AbstractFailDescr): def __init__(self, identifier=None): self.identifier = identifier # for testing -class AbstractMethDescr(AbstractDescr): - # the base class of the result of cpu.methdescrof() - jitcodes = None - def setup(self, jitcodes): - # jitcodes maps { runtimeClass -> jitcode for runtimeClass.methname } - self.jitcodes = jitcodes - def get_jitcode_for_class(self, oocls): - return self.jitcodes[oocls] class Const(AbstractValue): __slots__ = () diff --git a/rpython/jit/metainterp/optimizeopt/virtualstate.py b/rpython/jit/metainterp/optimizeopt/virtualstate.py --- a/rpython/jit/metainterp/optimizeopt/virtualstate.py +++ b/rpython/jit/metainterp/optimizeopt/virtualstate.py @@ -195,11 +195,10 @@ raise BadVirtualState if not value.is_virtual(): raise BadVirtualState + if len(self.fieldstate) > value.getlength(): + raise BadVirtualState for i in range(len(self.fieldstate)): - try: - v = value.get_item_value(i) - except IndexError: - raise BadVirtualState + v = value.get_item_value(i) s = self.fieldstate[i] if s.position > self.position: s.enum_forced_boxes(boxes, v, optimizer) @@ -269,13 +268,13 @@ raise BadVirtualState if not value.is_virtual(): raise BadVirtualState + if len(self.fielddescrs) > len(value._items): + raise BadVirtualState p = 0 for i in range(len(self.fielddescrs)): for j in range(len(self.fielddescrs[i])): try: v = value._items[i][self.fielddescrs[i][j]] - except IndexError: - raise BadVirtualState except KeyError: raise BadVirtualState s = self.fieldstate[p] diff --git a/rpython/jit/metainterp/test/test_immutable.py b/rpython/jit/metainterp/test/test_immutable.py --- a/rpython/jit/metainterp/test/test_immutable.py +++ b/rpython/jit/metainterp/test/test_immutable.py @@ -69,6 +69,28 @@ self.check_operations_history(getfield_gc=0, getfield_gc_pure=1, getarrayitem_gc=0, getarrayitem_gc_pure=1) + def test_array_index_error(self): + class X(object): + _immutable_fields_ = ["y[*]"] + + def __init__(self, x): + self.y = x + + def get(self, index): + try: + return self.y[index] + except IndexError: + return -41 + + def f(index): + l = [1, 2, 3, 4] + l[2] = 30 + a = escape(X(l)) + return a.get(index) + res = self.interp_operations(f, [2], listops=True) + assert res == 30 + self.check_operations_history(getfield_gc=0, getfield_gc_pure=1, + getarrayitem_gc=0, getarrayitem_gc_pure=1) def test_array_in_immutable(self): class X(object): diff --git a/rpython/jit/tl/targettlc.py b/rpython/jit/tl/targettlc.py --- a/rpython/jit/tl/targettlc.py +++ b/rpython/jit/tl/targettlc.py @@ -2,7 +2,6 @@ import py py.path.local(__file__) from rpython.jit.tl.tlc import interp, interp_nonjit, ConstantPool -from rpython.jit.codewriter.policy import JitPolicy from rpython.jit.backend.hlinfo import highleveljitinfo @@ -54,14 +53,10 @@ return decode_program(f.readall()) def target(driver, args): - return entry_point, None + return entry_point # ____________________________________________________________ -def jitpolicy(driver): - """Returns the JIT policy to use when translating.""" - return JitPolicy() - if __name__ == '__main__': import sys sys.exit(entry_point(sys.argv)) diff --git a/rpython/jit/tl/targettlr.py b/rpython/jit/tl/targettlr.py --- a/rpython/jit/tl/targettlr.py +++ b/rpython/jit/tl/targettlr.py @@ -29,15 +29,10 @@ return bytecode def target(driver, args): - return entry_point, None + return entry_point # ____________________________________________________________ -from rpython.jit.codewriter.policy import JitPolicy - -def jitpolicy(driver): - return JitPolicy() - if __name__ == '__main__': import sys sys.exit(entry_point(sys.argv)) diff --git a/rpython/jit/tl/tla/targettla.py b/rpython/jit/tl/tla/targettla.py --- a/rpython/jit/tl/tla/targettla.py +++ b/rpython/jit/tl/tla/targettla.py @@ -28,9 +28,6 @@ def target(driver, args): return entry_point, None -def jitpolicy(driver): - from rpython.jit.codewriter.policy import JitPolicy - return JitPolicy() # ____________________________________________________________ diff --git a/rpython/memory/gctransform/asmgcroot.py b/rpython/memory/gctransform/asmgcroot.py --- a/rpython/memory/gctransform/asmgcroot.py +++ b/rpython/memory/gctransform/asmgcroot.py @@ -729,6 +729,10 @@ # - frame address (actually the addr of the retaddr of the current function; # that's the last word of the frame in memory) # +# On 64 bits, it is an array of 7 values instead of 5: +# +# - %rbx, %r12, %r13, %r14, %r15, %rbp; and the frame address +# if IS_64_BITS: CALLEE_SAVED_REGS = 6 diff --git a/rpython/rlib/longlong2float.py b/rpython/rlib/longlong2float.py --- a/rpython/rlib/longlong2float.py +++ b/rpython/rlib/longlong2float.py @@ -68,14 +68,12 @@ uint2singlefloat = rffi.llexternal( "pypy__uint2singlefloat", [rffi.UINT], rffi.FLOAT, _callable=uint2singlefloat_emulator, compilation_info=eci, - _nowrapper=True, elidable_function=True, sandboxsafe=True, - oo_primitive="pypy__uint2singlefloat") + _nowrapper=True, elidable_function=True, sandboxsafe=True) singlefloat2uint = rffi.llexternal( "pypy__singlefloat2uint", [rffi.FLOAT], rffi.UINT, _callable=singlefloat2uint_emulator, compilation_info=eci, - _nowrapper=True, elidable_function=True, sandboxsafe=True, - oo_primitive="pypy__singlefloat2uint") + _nowrapper=True, elidable_function=True, sandboxsafe=True) class Float2LongLongEntry(ExtRegistryEntry): diff --git a/rpython/rlib/rlocale.py b/rpython/rlib/rlocale.py --- a/rpython/rlib/rlocale.py +++ b/rpython/rlib/rlocale.py @@ -193,11 +193,11 @@ raise LocaleError("unsupported locale setting") return rffi.charp2str(ll_result) -isalpha = external('isalpha', [rffi.INT], rffi.INT, oo_primitive='locale_isalpha') -isupper = external('isupper', [rffi.INT], rffi.INT, oo_primitive='locale_isupper') -islower = external('islower', [rffi.INT], rffi.INT, oo_primitive='locale_islower') -tolower = external('tolower', [rffi.INT], rffi.INT, oo_primitive='locale_tolower') -isalnum = external('isalnum', [rffi.INT], rffi.INT, oo_primitive='locale_isalnum') +isalpha = external('isalpha', [rffi.INT], rffi.INT) +isupper = external('isupper', [rffi.INT], rffi.INT) +islower = external('islower', [rffi.INT], rffi.INT) +tolower = external('tolower', [rffi.INT], rffi.INT) +isalnum = external('isalnum', [rffi.INT], rffi.INT) if HAVE_LANGINFO: _nl_langinfo = external('nl_langinfo', [rffi.INT], rffi.CCHARP) diff --git a/rpython/rlib/streamio.py b/rpython/rlib/streamio.py --- a/rpython/rlib/streamio.py +++ b/rpython/rlib/streamio.py @@ -185,11 +185,8 @@ SetEndOfFile = rffi.llexternal('SetEndOfFile', [HANDLE], BOOL, compilation_info=_eci) - # HACK: These implementations are specific to MSVCRT and the C backend. - # When generating on CLI or JVM, these are patched out. - # See PyPyTarget.target() in targetpypystandalone.py def _setfd_binary(fd): - #Allow this to succeed on invalid fd's + # Allow this to succeed on invalid fd's if rposix.is_valid_fd(fd): _setmode(fd, os.O_BINARY) 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 @@ -62,8 +62,8 @@ compilation_info=ExternalCompilationInfo(), sandboxsafe=False, threadsafe='auto', _nowrapper=False, calling_conv='c', - oo_primitive=None, elidable_function=False, - macro=None, random_effects_on_gcobjs='auto'): + elidable_function=False, macro=None, + random_effects_on_gcobjs='auto'): """Build an external function that will invoke the C function 'name' with the given 'args' types and 'result' type. @@ -97,8 +97,6 @@ if elidable_function: _callable._elidable_function_ = True kwds = {} - if oo_primitive: - kwds['oo_primitive'] = oo_primitive has_callback = False for ARG in args: @@ -651,6 +649,10 @@ # char * CCHARP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True})) +# const char * +CONST_CCHARP = lltype.Ptr(lltype.Array(lltype.Char, hints={'nolength': True, + 'render_as_const': True})) + # wchar_t * CWCHARP = lltype.Ptr(lltype.Array(lltype.UniChar, hints={'nolength': True})) diff --git a/rpython/rtyper/rlist.py b/rpython/rtyper/rlist.py --- a/rpython/rtyper/rlist.py +++ b/rpython/rtyper/rlist.py @@ -247,27 +247,22 @@ v_lst, v_index = hop.inputargs(r_lst, Signed) if checkidx: hop.exception_is_here() + spec = dum_checkidx else: + spec = dum_nocheck hop.exception_cannot_occur() - if hop.args_s[0].listdef.listitem.mutated or checkidx: - if hop.args_s[1].nonneg: - llfn = ll_getitem_nonneg - else: - llfn = ll_getitem - if checkidx: - spec = dum_checkidx - else: - spec = dum_nocheck - c_func_marker = hop.inputconst(Void, spec) - v_res = hop.gendirectcall(llfn, c_func_marker, v_lst, v_index) + if hop.args_s[0].listdef.listitem.mutated: + basegetitem = ll_getitem_fast else: - # this is the 'foldable' version, which is not used when - # we check for IndexError - if hop.args_s[1].nonneg: - llfn = ll_getitem_foldable_nonneg - else: - llfn = ll_getitem_foldable - v_res = hop.gendirectcall(llfn, v_lst, v_index) + basegetitem = ll_getitem_foldable_nonneg + + if hop.args_s[1].nonneg: + llfn = ll_getitem_nonneg + else: + llfn = ll_getitem + c_func_marker = hop.inputconst(Void, spec) + c_basegetitem = hop.inputconst(Void, basegetitem) + v_res = hop.gendirectcall(llfn, c_func_marker, c_basegetitem, v_lst, v_index) return r_lst.recast(hop.llops, v_res) rtype_getitem_key = rtype_getitem @@ -654,16 +649,16 @@ i += 1 length_1_i -= 1 -def ll_getitem_nonneg(func, l, index): +def ll_getitem_nonneg(func, basegetitem, l, index): ll_assert(index >= 0, "unexpectedly negative list getitem index") if func is dum_checkidx: if index >= l.ll_length(): raise IndexError - return l.ll_getitem_fast(index) + return basegetitem(l, index) ll_getitem_nonneg._always_inline_ = True # no oopspec -- the function is inlined by the JIT -def ll_getitem(func, l, index): +def ll_getitem(func, basegetitem, l, index): if func is dum_checkidx: length = l.ll_length() # common case: 0 <= index < length if r_uint(index) >= r_uint(length): @@ -680,21 +675,18 @@ if index < 0: index += l.ll_length() ll_assert(index >= 0, "negative list getitem index out of bound") + return basegetitem(l, index) +# no oopspec -- the function is inlined by the JIT + +def ll_getitem_fast(l, index): return l.ll_getitem_fast(index) -# no oopspec -- the function is inlined by the JIT +ll_getitem_fast._always_inline_ = True def ll_getitem_foldable_nonneg(l, index): ll_assert(index >= 0, "unexpectedly negative list getitem index") return l.ll_getitem_fast(index) ll_getitem_foldable_nonneg.oopspec = 'list.getitem_foldable(l, index)' -def ll_getitem_foldable(l, index): - if index < 0: - index += l.ll_length() - return ll_getitem_foldable_nonneg(l, index) -ll_getitem_foldable._always_inline_ = True -# no oopspec -- the function is inlined by the JIT - def ll_setitem_nonneg(func, l, index, newitem): ll_assert(index >= 0, "unexpectedly negative list setitem index") if func is dum_checkidx: diff --git a/rpython/rtyper/rtyper.py b/rpython/rtyper/rtyper.py --- a/rpython/rtyper/rtyper.py +++ b/rpython/rtyper/rtyper.py @@ -58,7 +58,6 @@ self.classdef_to_pytypeobject = {} self.concrete_calltables = {} self.class_pbc_attributes = {} - self.oo_meth_impls = {} self.cache_dummy_values = {} self.lltype2vtable = {} self.typererrors = [] diff --git a/rpython/rtyper/test/test_rlist.py b/rpython/rtyper/test/test_rlist.py --- a/rpython/rtyper/test/test_rlist.py +++ b/rpython/rtyper/test/test_rlist.py @@ -14,15 +14,19 @@ from rpython.translator.translator import TranslationContext -# undo the specialization parameter +# undo the specialization parameters for n1 in 'get set del'.split(): + if n1 == "get": + extraarg = "ll_getitem_fast, " + else: + extraarg = "" for n2 in '', '_nonneg': name = 'll_%sitem%s' % (n1, n2) globals()['_' + name] = globals()[name] exec """if 1: def %s(*args): - return _%s(dum_checkidx, *args) -""" % (name, name) + return _%s(dum_checkidx, %s*args) +""" % (name, name, extraarg) del n1, n2, name @@ -1400,7 +1404,7 @@ block = graph.startblock op = block.operations[-1] assert op.opname == 'direct_call' - func = op.args[0].value._obj._callable + func = op.args[2].value assert ('foldable' in func.func_name) == \ ("y[*]" in immutable_fields) @@ -1511,8 +1515,8 @@ block = graph.startblock lst1_getitem_op = block.operations[-3] # XXX graph fishing lst2_getitem_op = block.operations[-2] - func1 = lst1_getitem_op.args[0].value._obj._callable - func2 = lst2_getitem_op.args[0].value._obj._callable + func1 = lst1_getitem_op.args[2].value + func2 = lst2_getitem_op.args[2].value assert func1.oopspec == 'list.getitem_foldable(l, index)' assert not hasattr(func2, 'oopspec') diff --git a/rpython/rtyper/test/test_runicode.py b/rpython/rtyper/test/test_runicode.py --- a/rpython/rtyper/test/test_runicode.py +++ b/rpython/rtyper/test/test_runicode.py @@ -8,7 +8,7 @@ # ====> test_rstr.py -class BaseTestRUnicode(AbstractTestRstr, BaseRtypingTest): +class TestRUnicode(AbstractTestRstr, BaseRtypingTest): const = unicode constchar = unichr diff --git a/rpython/translator/backendopt/test/test_removenoops.py b/rpython/translator/backendopt/test/test_removenoops.py --- a/rpython/translator/backendopt/test/test_removenoops.py +++ b/rpython/translator/backendopt/test/test_removenoops.py @@ -97,9 +97,8 @@ def test_remove_unaryops(): - # We really want to use remove_unaryops for things like ooupcast and - # oodowncast in dynamically typed languages, but it's easier to test - # it with operations on ints here. + # We really want to use remove_unaryops for more complex operations, but + # it's easier to test it with operations on ints here. def f(x): i = llop.int_invert(lltype.Signed, x) i = llop.int_add(lltype.Signed, x, 1) diff --git a/rpython/translator/c/node.py b/rpython/translator/c/node.py --- a/rpython/translator/c/node.py +++ b/rpython/translator/c/node.py @@ -358,6 +358,8 @@ self.fullptrtypename = 'void *@' else: self.fullptrtypename = self.itemtypename.replace('@', '*@') + if ARRAY._hints.get("render_as_const"): + self.fullptrtypename = 'const ' + self.fullptrtypename def setup(self): """Array loops are forbidden by ForwardReference.become() because diff --git a/rpython/translator/c/test/test_lltyped.py b/rpython/translator/c/test/test_lltyped.py --- a/rpython/translator/c/test/test_lltyped.py +++ b/rpython/translator/c/test/test_lltyped.py @@ -1,5 +1,6 @@ import py from rpython.rtyper.lltypesystem.lltype import * +from rpython.rtyper.lltypesystem import rffi from rpython.translator.c.test.test_genc import compile from rpython.tool.sourcetools import func_with_new_name @@ -314,14 +315,14 @@ from rpython.rtyper.lltypesystem.rstr import STR from rpython.rtyper.lltypesystem import rffi, llmemory, lltype P = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1)) - + def f(): a = llstr("xyz") b = (llmemory.cast_ptr_to_adr(a) + llmemory.offsetof(STR, 'chars') + llmemory.itemoffsetof(STR.chars, 0)) buf = rffi.cast(rffi.VOIDP, b) return buf[2] - + fn = self.getcompiled(f, []) res = fn() assert res == 'z' @@ -941,3 +942,21 @@ assert fn(0) == 10 assert fn(1) == 10 + 521 assert fn(2) == 10 + 34 + + def test_const_char_star(self): + from rpython.translator.tool.cbuild import ExternalCompilationInfo + + eci = ExternalCompilationInfo(includes=["stdlib.h"]) + atoi = rffi.llexternal('atoi', [rffi.CONST_CCHARP], rffi.INT, + compilation_info=eci) + + def f(n): + s = malloc(rffi.CCHARP.TO, 2, flavor='raw') + s[0] = '9' + s[1] = '\0' + res = atoi(rffi.cast(rffi.CONST_CCHARP, s)) + free(s, flavor='raw') + return res + + fn = self.getcompiled(f, [int]) + assert fn(0) == 9 diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -354,8 +354,12 @@ """ Generate bytecodes for JIT and flow the JIT helper functions lltype version """ - get_policy = self.extra['jitpolicy'] - self.jitpolicy = get_policy(self) + from rpython.jit.codewriter.policy import JitPolicy + get_policy = self.extra.get('jitpolicy', None) + if get_policy is None: + self.jitpolicy = JitPolicy() + else: + self.jitpolicy = get_policy(self) # from rpython.jit.metainterp.warmspot import apply_jit apply_jit(self.translator, policy=self.jitpolicy, @@ -544,9 +548,14 @@ try: entry_point, inputtypes, policy = spec + except TypeError: + # not a tuple at all + entry_point = spec + inputtypes = policy = None except ValueError: + policy = None entry_point, inputtypes = spec - policy = None + driver.setup(entry_point, inputtypes, policy=policy, diff --git a/rpython/translator/goal/targetjitstandalone.py b/rpython/translator/goal/targetjitstandalone.py --- a/rpython/translator/goal/targetjitstandalone.py +++ b/rpython/translator/goal/targetjitstandalone.py @@ -3,7 +3,6 @@ """ from rpython.rlib import jit -from rpython.jit.codewriter.policy import JitPolicy driver = jit.JitDriver(greens = [], reds = 'auto') driver2 = jit.JitDriver(greens = [], reds = 'auto') @@ -40,7 +39,4 @@ return 0 def target(*args): - return entry_point, None - -def jitpolicy(driver): - return JitPolicy() + return entry_point diff --git a/rpython/translator/goal/targetnopstandalone.py b/rpython/translator/goal/targetnopstandalone.py --- a/rpython/translator/goal/targetnopstandalone.py +++ b/rpython/translator/goal/targetnopstandalone.py @@ -19,4 +19,4 @@ # _____ Define and setup target ___ def target(*args): - return entry_point, None + return entry_point diff --git a/rpython/translator/goal/targetrpystonedalone.py b/rpython/translator/goal/targetrpystonedalone.py --- a/rpython/translator/goal/targetrpystonedalone.py +++ b/rpython/translator/goal/targetrpystonedalone.py @@ -60,13 +60,12 @@ # _____ Define and setup target ___ def target(*args): - return entry_point, None + return entry_point """ Why is this a stand-alone target? -The above target specifies None as the argument types list. -This is a case treated specially in the driver.py . If the list -of input types is empty, it is meant to be a list of strings, -actually implementing argv of the executable. +The above target specifies no argument types list. +This is a case treated specially in the driver.py . The only argument is meant +to be a list of strings, actually implementing argv of the executable. """ diff --git a/rpython/translator/goal/translate.py b/rpython/translator/goal/translate.py --- a/rpython/translator/goal/translate.py +++ b/rpython/translator/goal/translate.py @@ -284,8 +284,6 @@ default_goal='compile') log_config(translateconfig, "translate.py configuration") if config.translation.jit: - if 'jitpolicy' not in targetspec_dic: - raise Exception('target has no jitpolicy defined.') if (translateconfig.goals != ['annotate'] and translateconfig.goals != ['rtype']): drv.set_extra_goals(['pyjitpl']) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit